【问题标题】:VBA Macro lost after saving and closing as xslm保存并关闭为 xslm 后 VBA 宏丢失
【发布时间】:2017-02-07 12:57:27
【问题描述】:

我的情况:我有一个 Excel 工作簿,它应该创建一个以 xslm 作为文件扩展名的新工作簿,编辑单个工作表的名称并将一些数据放入其中。

在创建 ComboBox 并用数据填充 ComboBox 之后,在新工作簿中创建一个具有 ComboBox1_Change Sub 的宏。

当所有这些都完成后,新的工作簿被保存并关闭。

现在的问题是,如果我重新打开工作簿,组合框是空的,并且宏不再在工作簿中。 经过一些研究,我发现这个问题是人们将工作表保存为 xlsx 而不是 xslm,但我确保我的代码不是这种情况。

也许我忽略了一些东西,但我什至在 close 命令上设置了一个断点,以检查一切是否正常,并且它会在此之前完成它应该做的事情。所以问题必须在close和save之内。 我什至尝试将其保存并单独关闭,或者将新工作簿设置为活动并保存。 也许这里有人可以帮助我。

编辑:我正在使用 Excel 2007

提前致谢,代码如下:

创建新工作簿的子:

Sub createTemplate()
Dim currentWB As Workbook
Set currentWB = ThisWorkbook
Dim template As Workbook
Dim curResSht As Worksheet
Dim temUtiSht As Worksheet
Dim curHolSht As Worksheet
Dim temHolSht As Worksheet
Workbooks.Add
Set curResSht = currentWB.Worksheets("Resource Plan")
Set curHolSht = currentWB.Worksheets("Holidays")
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=currentWB.Path & "\Template.xlsm", FileFormat:=52
Set template = ActiveWorkbook
template.Sheets(3).name = "Holidays"
template.Sheets(2).name = "Person List"
template.Sheets(2).Visible = False
template.Sheets(1).name = "Utilisation"
Set temUtiSht = template.Worksheets("Utilisation")
Set temHolSht = template.Worksheets("Holidays")
For i = 1 To 4
    curResSht.Rows(i).EntireRow.Copy
    temUtiSht.Rows(i).EntireRow.PasteSpecial
Next i

For i = 1 To 3
    curHolSht.Rows(i).EntireRow.Copy
    temHolSht.Rows(i).EntireRow.PasteSpecial
Next i

Application.DisplayAlerts = True

Dim curDatSht As Worksheet
Dim temLisSht As Worksheet
Set curDatSht = currentWB.Worksheets("Data")
Set temLisSht = template.Worksheets("Person List")
i = 5
Dim j As Integer
j = 1
While Not IsEmpty(curResSht.Cells(i, 1))
    If curResSht.Cells(i, 1).Interior.Color = curDatSht.Cells(2, 1).Interior.Color Then GoTo skipLine
    If curResSht.Cells(i, 3).Value = "Total" Then GoTo skipLine
    For k = 1 To 7
        curResSht.Cells(i, k).Copy
        temLisSht.Cells(j, k).PasteSpecial
    Next k
    j = j + 1
skipLine:
    i = i + 1
Wend

Set temCom = temUtiSht.OLEObjects.Add(ClassType:="Forms.ComboBox.1", Link:=False, DisplayAsIcon:=False, Left:=49, Top:=30, Width:=200, Height:=25)
template.Save
template.Close
Workbooks.Open (currentWB.Path & "\Template.xlsm")
Call fillEmpInLis
Call createCodeInTemplate
Application.Workbooks("Template.xlsm").Close savechanges:=True
End Sub

宏创建子:

Sub createCodeInTemplate()
Dim tmWB As Workbook
Dim tmVP As VBProject
Dim tmVC As VBComponent
Dim tmCM As CodeModule

Set tmWB = Application.Workbooks("Template.xlsm")
Set tmVP = tmWB.VBProject
Set tmVC = tmVP.VBComponents("Sheet1")
Set tmCM = tmVC.CodeModule

With tmCM
    .InsertLines 1, "Private Sub ComboBox1_Change()"
    .InsertLines 2, vbTab & "Dim sht As Worksheet"
    .InsertLines 3, vbTab & "Dim sht2 As Worksheet"
    .InsertLines 4, vbTab & "Dim sht3 As Worksheet"
    .InsertLines 5, vbTab & "Set sht = ThisWorkbook.Worksheets(""Utilisation"")"
    .InsertLines 6, vbTab & "Set sht2 = ThisWorkbook.Worksheets(""Person List"")"
    .InsertLines 7, vbTab & "Set sht3 = ThisWorkbook.Worksheets(""Holidays"")"
    .InsertLines 8, vbTab & "Dim k As Integer"
    .InsertLines 9, vbTab & "k = 4"
    .InsertLines 10, vbTab & "Dim i As Integer"
    .InsertLines 11, vbTab & "i = 5"
    .InsertLines 12, vbTab & "Dim j As Integer"
    .InsertLines 13, vbTab & "j = 1"
    .InsertLines 14, vbTab & "While Not IsEmpty(sht.Cells(i, 1))"
    .InsertLines 15, vbTab & vbTab & "i = i + 1"
    .InsertLines 16, vbTab & "Wend"
    .InsertLines 17, vbTab & "While Not IsEmpty(sht3.Cells(k, 1))"
    .InsertLines 18, vbTab & vbTab & "k = k + 1"
    .InsertLines 19, vbTab & "Wend"
    .InsertLines 20, vbTab & "While Not IsEmpty(sht2.Cells(j, 1))"
    .InsertLines 21, vbTab & vbTab & "If sht2.Cells(j, 1).Value = ComboBox1.Value Then"
    .InsertLines 22, vbTab & vbTab & vbTab & "sht2.Rows(j).EntireRow.Copy"
    .InsertLines 23, vbTab & vbTab & vbTab & "sht.Rows(i).EntireRow.PasteSpecial"
    .InsertLines 24, vbTab & vbTab & vbTab & "sht2.Cells(i, 1).Copy"
    .InsertLines 25, vbTab & vbTab & vbTab & "sht3.Cells(k, 2).PasteSpecial"
    .InsertLines 26, vbTab & vbTab & vbTab & "sht2.Cells(i, 2).Copy"
    .InsertLines 27, vbTab & vbTab & vbTab & "sht3.Cells(k, 1).PasteSpecial"
    .InsertLines 28, vbTab & vbTab & vbTab & "k = k + 1"
    .InsertLines 29, vbTab & vbTab & vbTab & "i = i + 1"
    .InsertLines 30, vbTab & vbTab & "End If"
    .InsertLines 31, vbTab & vbTab & "j = j + 1"
    .InsertLines 32, vbTab & "Wend"
    .InsertLines 33, "End Sub"
End With
End Sub

以及填充 ComboBox 的 Sub:

Sub fillEmpInLis()
Dim wb As Workbook
Dim utiSht As Worksheet
Dim perSht As Worksheet
Set wb = Application.Workbooks("Template.xlsm")
Set utiSht = wb.Worksheets("Utilisation")
Set perSht = wb.Worksheets("Person List")
Set box = wb.Sheets("Utilisation").ComboBox1
box.Clear
Dim i As Integer
i = 2

box.AddItem perSht.Cells(1, 1).Value
While Not IsEmpty(perSht.Cells(i, 1))
    Dim resultIndex As Boolean
    resultIndex = False
    For j = 0 To box.ListCount - 1
        If box.List(j) = perSht.Cells(i, 1).Value Then
            resultIndex = True
        End If
    Next j
    If resultIndex = False Then
        For j = 0 To box.ListCount - 1
            If perSht.Cells(i, 1) < box.List(j) And j = 0 Then
                box.AddItem perSht.Cells(i, 1), j
                GoTo skip
            ElseIf perSht.Cells(i, 1) > box.List(j) And j = box.ListCount - 1 Then
                box.AddItem perSht.Cells(i, 1)
                GoTo skip
            ElseIf perSht.Cells(i, 1) > box.List(j) And perSht.Cells(i, 1) < box.List(j + 1) Then
                box.AddItem perSht.Cells(i, 1), j
                GoTo skip
            End If
        Next j
skip:
    End If
    i = i + 1
Wend
End Sub

【问题讨论】:

  • 您使用的是什么版本的 Excel?
  • 手动创建一个包含代码和控件的模板工作簿然后在您的代码中使用它不是更容易吗?如果用户已将 Excel 选项设置为使用单个工作表创建新工作簿,您的代码也会失败 - 不会有工作表可重命名“假期”和“人员列表”。
  • 我添加了我正在使用的 Excel 版本 (2007)。 @DarrenBartrup-Cook 是的,这可能更容易,但我这样做是因为如果主工作簿中有更改,模板将不得不更改,并且用户按下按钮创建新版本更快更容易模板,而不是每次都手动创建新版本
  • 如果您已经完成了“另存为”,那么为什么需要复制/粘贴信息和宏代码呢?无论如何,它应该都在那里?
  • @Macro Man 我不明白你的意思

标签: vba excel macros


【解决方案1】:

我希望这会有所帮助:

我的猜测是宏代码在保存时没有在模板中正确创建。所以我只是将您的代码复制到一个空的工作簿中,并在创建您的宏代码的 Sub 中进行了这些更改:

Sub createCodeInTemplate()
  Dim tmWB As Workbook

    Set tmWB = Application.Workbooks("Template.xlsm")

    With tmWB.VBProject.VBComponents(tmWB.Sheets("Utilisation").CodeName).CodeModule

然后我测试了完整的代码,创建的文件 (Template.xlsm) 包含宏代码。

由于我使用的是 Excel 2013,它可能对您没有帮助,但我会试一试。

【讨论】:

  • 感谢您的回答,但它对我不起作用。我猜主要的斗争点仍然是保存和关闭,因为如果我不关闭它,代码就在工作表中。即使我在检查代码后手动保存并重新打开它,代码也没有了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
相关资源
最近更新 更多