【问题标题】:How to Edit "This Workbook" macro with another macro如何使用另一个宏编辑“此工作簿”宏
【发布时间】:2019-02-18 06:12:47
【问题描述】:

只是另一个问题,希望有人可以帮助我。

对于那些过去帮助过我的人,我非常感谢这个社区,我很高兴能成为其中的一员。

这里有一些背景信息。

我从主列表(theFILE 1.1.xlsm)中创建了大约 3200 个 excel 工作簿,每个工作簿都是从主列表中的一行编译而来的。

现在我已经能够使用此代码编辑工作表和单元格了;

Sub Macro2()

Application.ScreenUpdating = False

Dim sFile As String
Dim wb As Workbook
Dim FileName1 As String
Dim FileName2 As String
Dim wksSource As Worksheet
Const scWkbSourceName As String = "theFILE 1.1.xlsm"

Set wkbSource = Workbooks(scWkbSourceName)
Set wksSource = wkbSource.Sheets("Sheet1") ' Replace Sheet1 with the sheet name

Const wsOriginalBook As String = "theFILE 1.1.xlsm"
Const sPath As String = "E:\theFILES\" 

SourceRow = 5

Do While Cells(SourceRow, "D").Value <> ""

FileName1 = wksSource.Range("A" & SourceRow).Value
FileName2 = wksSource.Range("K" & SourceRow).Value

sFile = sPath & FileName1 & "\" & FileName2 & ".xlsm"

'Open Source Row's File
Set wb = Workbooks.Open(sFile)

'(INSERT CODE FOR SPECIFIED JOB)

'CLOSE WORKBOOK W/O BEFORE SAVE
Application.EnableEvents = False
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.EnableEvents = True

SourceRow = SourceRow + 1 ' Move down 1 row for source sheet

Loop

End Sub

请原谅我缺乏术语。

如果可能,我希望能够使用此代码打开每个工作簿并编辑“Microsoft Excel 对象”-“ThisWorkbook”中的行。这个模块,如果你可以这么称呼它的话,它包含一个 BeforeSave 函数,每次用户保存时都会在隐藏的电子表格中记录一些信息。

这是当前的“BeforeSave”宏

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

Dim ws As Worksheet
Set ws = Sheets("EDITS")
Dim tbl As ListObject
Set tbl = ws.ListObjects("Table1")
Dim newrow As ListRow
Set newrow = tbl.ListRows.Add

    SavePrompt.Show

With newrow
    .Range(1) = Now
    .Range(2) = SavePrompt.TextBox1.Text
End With

Unload SavePrompt

End Sub

我需要在其中添加 .Range(3)=Computer Name 和 .Range(4)=username。 我需要每个工作簿独立工作,因为主机可能会偶尔更改,其他人将无法重新链接或编辑 VBA。

首先是否可以编辑“Microsoft Excel 对象 - ThisWorkbook”

如果有怎么办?我试过了 ThisWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 13, "Test"

...在允许 Excel“信任对 VBA 项目对象模型的访问”后,我收到一条通知,说明“此时无法进入中断模式”,我选择了“继续”,而我的计算机没有就像代码一样,它确实像往常一样打开和关闭每个工作簿。它最终将“测试”添加到大师的“ThisWorkbook”中。主工作簿(theFILE 1.1.xlsm)中没有宏,所以它只是从外观上添加到下一个可用行。

然后我将最后一个代码更改为;

ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 13, "Test"

这似乎解决了错误,但随着计算机运行代码,它开始挂起,Excel 开始出现“未响应..”

所以如果这是可能的... 是否可以像在excel中右键单击一行时那样添加/插入一行并将前面的行向下移动1?

如果 Excel 不允许编辑“ThisWorkbook”中的行,那么我该如何彻底检查对象? (删除并导入更新的对象)

【问题讨论】:

  • 请检查this answer。这不是您想要的,但它解释了如何使用 VBA 本身编辑 VBA 代码。只需根据您的需要进行调整即可。
  • “没有响应”只是你的代码很忙。您可以可能在关闭Loop 之前添加DoEvents 再次让Excel 响应,但这可能会使其完成速度变慢。现在,您如何知道要插入的行是第 13 行?更好地找到您要替换的过程,找到它的开始+结束行,然后用您的新代码替换这些行(无论它们是什么)。第一步是在Loop 处设置断点,并验证您的代码是否正在执行它需要执行的操作,然后一次性破坏 3000 个文件;-)
  • ThisWorkbook(标识符)将始终引用当前正在运行您正在查看的代码的工作簿"ThisWorkbook"(组件名称)指的是父 VBProject 的“ThisWorkbook”VBComponent。这就是您无法进入中断模式的原因(this workbook 中的代码已被修改,并且还没有机会重新编译),以及为什么将 VBProject 引用从ActiveWorkbook 中删除。也就是说wb.VBProject更加更安全。
  • 感谢您的反馈@MathieuGuindon,在我重新启动机器后它运行良好。但似乎已经占用空间的行和 VBA 将值放在下一个可用行上。这正常吗。如果是这样,我如何删除两个特定的行,以便我可以按程序顺序处理所有内容?
  • 引用 Visual Basic Extensibility 类型库,并声明类型化的局部变量,而不是链接 5 层深的成员调用 - 您将获得智能感知来指导您。例如声明currentProject As VBProject,然后是wbComponent As VBComponent,然后是wbModule As CodeModule;分配每一个,然后查看wbModule 有哪些成员 - 您会找到查找特定过程、它们从哪一行开始以及它们是多少行的方法。

标签: vba excel module


【解决方案1】:
Sub Macro2() '''EDIT THE MACRO ON "ThisWorkbook" MODULE
Application.ScreenUpdating = False

Dim sFile As String
Dim wb As Workbook
Dim FileName1 As String
Dim FileName2 As String
Dim wksSource As Worksheet
Const scWkbSourceName As String = "theFILE 1.1.xlsm"

Set wkbSource = Workbooks(scWkbSourceName)
Set wksSource = wkbSource.Sheets("Sheet1") ' Replace Sheet1 with the sheet name

Const wsOriginalBook As String = "theFILE 1.1.xlsm"
Const sPath As String = "E:\theFILES\" 'this is PATH(!REMEMBER! to include "\")

SourceRow = 5

Do While Cells(SourceRow, "D").Value <> ""

FileName1 = wksSource.Range("A" & SourceRow).Value
FileName2 = wksSource.Range("K" & SourceRow).Value

sFile = sPath & FileName1 & "\" & FileName2 & ".xlsm"

Set wb = Workbooks.Open(sFile)

'''EDIT THE MACRO ON "ThisWorkbook" MODULE - FOR EACH PLANT's Workbook
'Deleting Lines
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 27
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 25
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 21
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 19
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 18
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 17
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 16
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 12
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.deleteLines 10

'Add DIM Lines
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 10, "'DIM SOME MORE OBJECTS"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 11, "Dim computername As String"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 12, "Dim username As String"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 13, "computername = Environ(""computername"")"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 14, "username = Environ(""username"")"

'Add the Lines Back
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 16, "    SavePrompt.Show"

ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 17, "'If SavePrompt.TextBox1 > 0 Then"

ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 18, "With newrow"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 19, "    .Range(1) = Now"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 20, "    .Range(2) = SavePrompt.TextBox1.Text"

'Add New Range LINES
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 21, "    .Range(3) = computername"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 22, "    .Range(4) = username"

'Continue Adding Lines back
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 24, "End With"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 25, "'ElseIf"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 26, "Unload SavePrompt"
ActiveWorkbook.VBProject.VBComponents("ThisWorkbook").CodeModule.insertLines 28, "End Sub"

'''CLOSE WORKBOOK W/O BEFORE SAVE
Application.EnableEvents = False
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.EnableEvents = True

SourceRow = SourceRow + 1 
Loop

End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多