所以,在我的VBA进程中,我的工作簿中有一个子表创建表单,并动态地将代码添加到新的表单激活事件中。实际上这很酷。但是,我遇到了工作表代码名称的问题,当我去引用它时,新工作表没有分配代码名称。
用于获取对新工作表代码模块的引用的代码是:With ActiveWorkbook.VBProject.VBComponents(CName).CodeModule
其中CName是工作表代码名称。
我得到了CName:CName = Workbooks(ExcelFormName).Sheets(NewSheetName).CodeName
NewSheetName是全局常量。这总是有效的,因为此代码在与创建工作表相同的功能中执行,因此用户没有机会重命名工作表。
我通过测试(包括拔毛)发现,当我创建工作表时:Set ws = Sheets.Add(, After:=Sheets(Worksheets.count))
除非vbe窗口打开,否则表单未分配代码名称。我使用debug.print "Test " & ws.codename
确认代号是空白的 - ""
所以当我尝试使用代码名称引用工作表时,我收到了一个错误。我发现我能做的是:
Application.VBE.MainWindow.Visible = True
Application.VBE.MainWindow.WindowState = vbext_ws_Minimize
在我创建工作表之前,快速打开并最小化VBE窗口(我后来关闭它),我不喜欢但它有效。但现在我遇到了一些问题,其中一些用户的安全设置不允许打开vbe窗口。
我注意到,刚才,如果我遍历工作簿中的所有vbcomponents,甚至没有进行任何处理:
Dim test As VBComponent
For Each test In ActiveWorkbook.VBProject.VBComponents
Next
然后在那之后,工作表有一个代码名称..所以我想知道,我还能做什么,除了循环通过这样的组件,以确保新工作表有一个代码名称,并且没有这样做,什么时候如果VBE窗口未打开,通常会为工作表分配其代码名称?
你的建议结果图片siddharth:
你可以看到,我添加了你的建议,我得到错误9,下标超出范围错误
Dim CName As Variant
CName = Workbooks(ExcelFormName).Sheets(NewSheetName).CodeName
With ActiveWorkbook.VBProject.VBComponents(CName).CodeModule
StartLine = .CreateEventProc("Activate", "worksheet") + 1
.InsertLines StartLine, "Dim numRows As Long"
.InsertLines StartLine + 1, "Dim numColumns as long"
.InsertLines StartLine + 2, "numRows = 0"
.InsertLines StartLine + 3, "numColumns = 0"
'mode codez
我正在动态地向新工作表激活事件添加代码。我会正常添加它但是当用户关闭书籍时会删除此工作表。这个特殊的表格不是一直需要的,所以我不希望它在那里,除非特定的用户需要它:)
答案 0 :(得分:1)
是的,这是一个非常古老的问题。要访问代号,请使用此
Dim ws As Worksheet
Set ws = Sheets.Add(, After:=Sheets(Worksheets.count))
Msgbox ThisWorkbook.VBProject.VBComponents(ws.Name).Properties("Codename")
但是要使此代码生效,您必须检查Trust access to the VBA-Project Object model
答案 1 :(得分:0)
在创建工作表后总结其他人阅读:
Dim ws As Worksheet
Set ws = Sheets.Add(, After:=Sheets(Worksheets.count))
使用:ws.name = ThisWorkbook.VBProject.VBComponents(ws.Name).Properties("Codename")
它不应该更改工作表名称,因为在重命名新工作表之前,名称与代号相同,但它会强制应用程序指定代号,而不是等到所有代码运行之后。
如果执行msgbox ws.codename
之类的代码而没有先使用ThisWorkbook.VBProject.VBComponents(ws.Name).Properties("Codename")
进行操作,那么ws.codename
将为空白