我经常使用这个网站,但这是我发布的第一个问题,希望我能提供足够的细节。我找不到任何相关的答案,因为无论我搜索什么,我都会得到与循环代码相关的各种答案。
一些背景: 我设计了一个Excel文档来跟踪我工作场所中的一些项目(以下简称主文档)。由于以前的跟踪器允许用户随时编辑任何内容,因此我使用了表单来确保所有信息都正确输入并安全存储。主文档中的每个项目都有一个单独的 Excel 工作簿(以下简称项目文档)。
主文档中有许多工作表,每次激活时都会运行代码(因为它们需要更新)。
由于每个项目文档中都有一些 VBA 代码,这对于与主文档同步数据至关重要,因此我添加了一个警告工作表,在没有宏的情况下打开项目文档时会显示该工作表。这涉及使用工作簿打开、保存前和保存后事件来确保仅显示警告而不显示宏。这是每个事件的代码(显然放置在 ThisWorkbook 模块中)
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Auto_Open
'This is for sync (Master Document checks for text file to see if any changes have been made to Item Document)
If booChange = True Then
Dim oFile As Object
Set oFile = fso.CreateTextFile(strTextFile)
SetAttr strTextFile, vbHidden
booChange = False
End If
'Turn off Screen Updating
Application.ScreenUpdating = False
'Show warning sheet
Sheets("Warning").Visible = xlSheetVisible
'Hide all sheets but Warning sheet
For Each sh In ThisWorkbook.Worksheets
If Not sh.Name = "Warning" Then sh.Visible = xlVeryHidden
Next sh
End Sub
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
'Show all sheets
For Each sh In ThisWorkbook.Worksheets
sh.Visible = xlSheetVisible
Next sh
'Hide the warning sheet
Sheets("Warning").Visible = xlVeryHidden
'Return focus to the main page
ThisWorkbook.Worksheets(1).Activate
'Turn on Screen Updating
Application.ScreenUpdating = True
ThisWorkbook.Saved = True
End Sub
Private Sub Workbook_Open()
'Turn off Screen Updating
Application.ScreenUpdating = False
'Show all sheets
For Each sh In ThisWorkbook.Worksheets
sh.Visible = xlSheetVisible
Next sh
'Hide the warning sheet
Sheets("Warning").Visible = xlVeryHidden
'Return focus to the main page
ThisWorkbook.Worksheets(1).Activate
'Turn on Screen Updating
Application.ScreenUpdating = True
ThisWorkbook.Saved = True
End Sub
为了完整起见,这里是项目文档 Module1 中的所有代码
'Declarations
'Strings
Public strSourceFolder As String
Public strTextFile As String
'Other
Public fso As FileSystemObject
Public booChange As Boolean
Public wsFlow As Worksheet
'Constants
Public Const strURNSheetName = "Part 1 Plant Flow Out Summ"
Sub Auto_Open()
Set fso = CreateObject("Scripting.FileSystemObject")
Set wsFlow = ThisWorkbook.Worksheets(strURNSheetName)
strSourceFolder = fso.Getfile(ThisWorkbook.FullName).ParentFolder.Path
strTextFile = fso.BuildPath(strSourceFolder, ThisWorkbook.Worksheets(strURNSheetName).Range("W2").Value & ".txt")
End Sub
当使用“frmNewEntry”表单在主文档中创建项目时,将检查信息并将其输入到主文档中,然后打开模板项目文档并使用新的唯一文件名保存。然后,它不 protected ,使用新信息进行更新, protected ,保存并关闭。然后保存主文档。代码如下(经过编辑以省略冗长的格式设置和数据输入):
表单代码:
Private Sub btnSave_Click()
'Values on form are verified
'Master Document sheet is unprotected, formatted and data entry occurs
'Clear Userform and close
For Each C In frmNewEntry.Controls
If TypeOf C Is MSForms.ComboBox Then
C.ListIndex = -1
ElseIf TypeOf C Is MSForms.TextBox Then
C.Text = ""
ElseIf TypeOf C Is MSForms.CheckBox Then
C.Value = False
End If
Next
frmNewEntry.Hide
'Create filepaths
Create_Filepath
'Some hyperlinks are added and the Master Document worksheet is protected again
'Create Flowout Summary
Create_Flowout_Summary
'Update Flowout Summary
Update_Flowout_Summary
'Turn on screen updating
Application.ScreenUpdating = True
'Update Activity Log
Update_Log ("New: " & strNewURN)
Debug.Print "Before Save Master"
'Save tracker
ThisWorkbook.Save
Debug.Print "After Save Master"
End Sub
模块1代码:
Public Sub Create_Flowout_Summary()
'Create a new flowout summary from the template
'Turn off screen updating
Application.ScreenUpdating = False
'Check if workbook is already open
If Not Is_Book_Open(strTemplate) Then
Application.Workbooks.Open (strTemplatePath)
End If
Debug.Print "Before SaveAs Create"
'Save as new flowout summary
Application.Workbooks(strTemplate).SaveAs fileName:=strFilePath
Debug.Print "After SaveAs Create"
'Close Document Information Panel
ActiveWorkbook.Application.DisplayDocumentInformationPanel = False 'Doesn't seem to work
'Turn on screen updating
Application.ScreenUpdating = True
End Sub
Public Sub Update_Flowout_Summary()
'Update the flowout summary for current call
Dim wsURN As Worksheet
Set wsURN = Workbooks(strFileName).Worksheets(strWsURNName)
'Unprotect Flowout Summary worksheet
wsURN.Unprotect "Flowout Summary"
'Write values to flowout summary
'Protect Flowout Summary worksheet
wsURN.Protect "Flowout Summary", False, True, True, True, True
Debug.Print "Before Save Update"
'Save flowout summary
Application.Workbooks(strFileName).Save
Debug.Print "After Save Update"
'Close Document Information Panel
ActiveWorkbook.Application.DisplayDocumentInformationPanel = False
'Turn on screen updating
Application.ScreenUpdating = True
End Sub
问题详细信息: 当我创建一个新条目时,需要很长时间,我意外地发现主文档正在每个工作表激活事件中运行代码(如上所述)(我在其中一张工作表中有一个诊断消息框,当我创建了一个新条目) 因此,我得出的结论是,代码以某种方式激活了每个工作表,但不知道为什么......
任何帮助将不胜感激,如果我错过了任何可能有助于诊断的内容,请告诉我。
编辑:另一个奇怪的现象是,当我尝试单步执行代码以准确找到激活事件被触发的位置时,这种情况不会发生。
编辑:工作表中的代码激活事件
Private Sub Worksheet_Activate()
'Turn off Screen Updating
Application.ScreenUpdating = False
'Simply writes data to the sheet (excluded because it is lengthy)
'Turn on Screen Updating
Application.ScreenUpdating = True
wsMyCalls.Protect Password:=strPassword
Debug.Print "wsMyCalls"
MsgBox "This sheet uses your username to display any calls you own." & vbNewLine & _
"It relies on the correct CDSID being entered for owner." & vbNewLine & vbNewLine & _
"Regards" & vbNewLine & _
"Your friendly spreadsheet administrator", vbOKOnly, "Information"
End Sub
编辑:我在代码中添加了一些 Debug.Prints(上面),这就是我得到的。
- 创建另存为之前
- 另存为创建后
- 保存更新之前
- 保存更新后
- 拯救大师之前
- 保存大师后
- wsMyCalls
这表明代码正在 Debug.Print“After Save Master”和 End Sub 之间执行。里面没有代码???
谢谢
最佳答案
我相信我们在这里没有看到您的完整代码。考虑到我们没有自己调试的工作簿,很难诊断。但是,我有一个类似的“欢迎”页面,每次打开我的一本工作簿时都会显示该页面,要求用户激活宏。我确实将 EnableEvents 设置为 false,并在保存之前将工作表置于某种状态,并在保存后将其放回原处。
我将向您详细展示我是如何做到这一点的,因为我感觉您的问题与未在正确的时间禁用 EnableEvents 有关。由于提到的代码不完整,我不确定如何根据您的工作簿的功能来计时。
该工作表称为 f_macros。这是阻止进一步导航的工作表激活事件:
Private Sub Worksheet_Activate()
ActiveWindow.DisplayHeadings = False
ActiveWindow.DisplayWorkbookTabs = False
End Sub
在我的 Workbook_BeforeSave 中:
我首先记录 DisplayHeadings 的当前状态等:
Dim Displaytabs As Boolean
Dim DisplayHeadings As Boolean
Dim menu As CommandBar
Dim ligne As CommandBarControl
Displaytabs = ActiveWindow.DisplayWorkbookTabs
DisplayHeadings = ActiveWindow.DisplayHeadings
然后,我重置自定义右键单击,关闭 EnableEvents 和屏幕更新。为了更好地衡量,我将 DisplayWorkbookTabs 设置为 false。
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.CommandBars("Cell").reset
ActiveWindow.DisplayWorkbookTabs = False
然后我运行 Cacherdata(HideData,下面附加的另一个模块中的子程序)保存,然后运行子 Macro_activees 以使工作簿恢复到用户的工作顺序。我重新打开 EnableEvents,并将标题恢复到原来的样子:
m_protection.Cacherdata
ThisWorkbook.Save
m_protection.macro_activees
Application.ScreenUpdating = True
Application.enableevents = True
ActiveWindow.DisplayWorkbookTabs = Displaytabs
ActiveWindow.DisplayHeadings = DisplayHeadings
我取消普通的保存(重要!)并指示工作簿已保存,以便他们可以正常退出而不会提示保存。
Cancel = True
ThisWorkbook.Saved = True
在BeforeClose中,它检查工作簿状态是否已保存。如果是,则退出。如果没有,它会执行类似的过程:
If Not (ThisWorkbook.Saved) Then
rep = MsgBox(Prompt:="Save changes before exiting?", _
Title:="---", _
Buttons:=vbYesNoCancel)
Select Case rep
Case vbYes
Application.ScreenUpdating = False
Application.enableevents = False
ActiveWindow.DisplayHeadings = True
m_protection.Cacherdata
ThisWorkbook.Save
Case vbCancel
Cancel = True
Exit Sub
End Select
End If
工作簿打开事件检查它是否是只读模式,但仅此而已。我没有 AfterSave 工作簿。
附件
CacherData 将每个工作表设置为 VeryHidden,这样用户就不会在不激活宏的情况下搞乱数据。它记录当前事件工作表,以便用户返回到原来的位置,取消对工作簿的保护,隐藏工作表,重新保护工作表,仅此而已:
Sub Cacherdata()
Dim ws As Worksheet
f_param.Range("page_active") = ActiveSheet.Name
f_macros.Activate
ThisWorkbook.Unprotect "-----"
For Each ws In ThisWorkbook.Worksheets
If ws.CodeName <> "f_macros" Then ws.visible = xlSheetVeryHidden
Next
ThisWorkbook.Protect "-----"
Exit Sub
End Sub
macros_activees 的作用相反:
Sub macro_activees()
Dim ws As Worksheet
ThisWorkbook.Unprotect "-----"
For Each ws In ThisWorkbook.Worksheets
ws.visible = xlSheetVisible
Next
ThisWorkbook.Sheets(f_param.Range("page_active").Value).Activate
ThisWorkbook.Unprotect "-----"
'it unportects twice because of the activate event of the worksheet, don't mind that
Exit Sub
End Sub
错误处理已被删除,因为它对显示毫无用处,但其他所有内容都应该在那里。
编辑:如果这对您没有任何帮助,也许您的问题是因为您创建的工作簿中的代码(9据我收集)可能会影响运行代码所需的时间?如果他们自己有一个开放程序,可能就是这样吗?
关于VBA 不需要的工作表循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32245475/