Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA新增:编译错误无效限定符。_Excel_Vba - Fatal编程技术网

Excel VBA新增:编译错误无效限定符。

Excel VBA新增:编译错误无效限定符。,excel,vba,Excel,Vba,此代码旨在获取原始数据的电子表格,省略几列,并重新设置剩余数据的格式。我欢迎对代码的任何和所有批评,因为我是VBA新手,什么都不知道。关键问题是代码的末尾,下面用astrics表示。这就是出现编译错误的地方:出现无效限定符。我试图将格式应用于B列和F列,但我只希望它一直到日期的最后一行。最后一行数据将随工作表的不同而变化 触发错误时,调试器将突出显示字数 提前感谢你的帮助 Sub Macro2() ' ' Macro2 Macro ' Union(Range("A:A"), Range("F:F

此代码旨在获取原始数据的电子表格,省略几列,并重新设置剩余数据的格式。我欢迎对代码的任何和所有批评,因为我是VBA新手,什么都不知道。关键问题是代码的末尾,下面用astrics表示。这就是出现编译错误的地方:出现无效限定符。我试图将格式应用于B列和F列,但我只希望它一直到日期的最后一行。最后一行数据将随工作表的不同而变化

触发错误时,调试器将突出显示字数

提前感谢你的帮助

Sub Macro2()
'
' Macro2 Macro
'
Union(Range("A:A"), Range("F:F"), Range("K:Q"), Range("S:V")).Delete
Range("A1").Select
ActiveCell.FormulaR1C1 = "FIRST"
Range("B1").Select
ActiveCell.FormulaR1C1 = "LAST"
Range("C1").Select
ActiveCell.FormulaR1C1 = "G"
Range("D1").Select
ActiveCell.FormulaR1C1 = "PHONE"
Range("E1").Select
ActiveCell.FormulaR1C1 = "ADDRESS"
Range("F1").Select
ActiveCell.FormulaR1C1 = "CITY"
Range("G1").Select
ActiveCell.FormulaR1C1 = "STATE"
Range("H1").Select
ActiveCell.FormulaR1C1 = "ZIP"
Range("I1").Select
ActiveCell.FormulaR1C1 = "MONTH"
Range("J1").Select
ActiveCell.FormulaR1C1 = "YEAR"
Columns("e:h").Insert Shift:=xlToRight
Columns("A:B").ColumnWidth = 12
Columns("C:C").ColumnWidth = 2
Columns("D:d").ColumnWidth = 13
Columns("e:e").ColumnWidth = 0.38
Columns("F:F").ColumnWidth = 5
Columns("G:G").ColumnWidth = 11
Columns("H:H").ColumnWidth = 0.38
Columns("I:N").ColumnWidth = 14
**Union(Range("B:B"),Range("F:F")).Rows.Count.End(xlUp).Row**
Range("B1").Activate
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent5
.TintAndShade = 0.599993896298105
.PatternTintAndShade = 0
End With


End Sub 

当我对通过字符串属性创建的对象类型感到困惑时,我会使用这种技术

在Excel的Visual Basic编辑器中,如果您没有希望以这种方式使用的现有模块,请创建一个新模块。如果在Project Explorer中选择该模块并单击F4,则可以将该模块的名称更改为

键入或复制:

Option Explicit
Sub TestA()

End Sub
我总是用Option Explicit启动模块。在VBA帮助中查找Option Explicit,它将告诉您为什么这是一个好主意

我还创建了一个空的子程序,我将在其中键入一些语句

开始键入一条新语句,以便:

Sub TestA()

  Debug.Print Range("B:B").

End Sub
在新行末尾键入句点时,弹出窗口将显示可用的方法和属性。此列表将按预期显示范围的所有方法和属性。键入地址或从列表中选择地址以获取:

Sub TestA()

  Debug.Print Range("B:B").Address

End Sub
单击F5运行此宏,立即窗口中将显示以下内容:

$B:$B
这是B列中所有行的地址,这是您所期望的

现在向宏中添加两个进一步的语句:

  Debug.Print Range("F:F").Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Count
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count
再次运行此宏,您将获得:

$B:$B
$F:$F
$B:$B,$F:$F
这也是人们所期望的

现在添加:

  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count.
出现的弹出窗口将保持不变,因为Range.Rows仍然是一个范围

通过添加或选择地址完成语句,然后再次运行宏以获取:

$B:$B
$F:$F
$B:$B,$F:$F
$B:$B,$F:$F
这可能不是你所期望的,但想想看$B:$B,$F:$F是B列和F列中的所有行,因此添加属性行不会更改地址

现在将以下语句添加到宏:

  Debug.Print Range("F:F").Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Count
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count
运行宏,这些语句将分别输出一个整数。我正在使用Excel 2003,因此我得到:

 131072 
 65536 
如果您使用的是更高版本的Excel,则会得到更大的整数。第二个整数是Excel版本工作表中的行数。第一个整数是Excel版本工作表中两列中的单元格数

现在添加:

  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count.
键入最后一个句点时,不会出现弹出窗口,因为整数没有可以通过这种方式选择的方法或属性。方法EndxlUp对一个范围进行操作;它不是Count的属性,这就是为什么会得到无效的限定符

将属性串在一起时,很容易让自己感到困惑。就我个人而言,我避免串接属性,因为即使它运行得更快,我也需要更长的时间来理解和调试。在某些情况下,最小化运行时间是首要任务,但这是其中之一吗?你用这种方法浪费了多少时间

考虑:

  Dim Rng1 As Range
  Dim Rng2 As Range
  Dim Rng3 As Range
  Dim RowMax As Long

  Set Rng1 = Range("B:B")
  Set Rng2 = Range("F:F")
  Set Rng3 = Union(Rng1, Rng2)
  RowMax = Rng3.Count

  Debug.Print RowMax

  Debug.Print Rng3.Find("*", Range("B1"), xlValues, xlWhole, xlByRows, xlPrevious).Row
Sub TestB()

  With Worksheets("Sheet1")
    .Range("A1").Value = "FIRST"
  End With

End Sub
  Dim Rng1 As Range

  With Worksheets("Sheet2")
    Set Rng1 = Union(Range("A:A"), Range("C:D"), Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
    Set Rng1 = Union(.Range("A:A"), .Range("C:D"), .Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
  End With
您不需要RowMax,但我已经包含了它,所以您完全清楚Rng3.Count返回的是什么。我也去了OTT的范围。我很乐意输入:Set Rng3=UnionRangeB:B,RangeF:F,因为我觉得这很容易理解

方法EndxlUp对单元格进行操作。MultiCellRange.EndxlUp.Row是有效的语法,但我无法让它返回有用的信息。如果要使用.EndxlUp,请考虑:

  Dim RowMaxColB As Long
  Dim RowMaxColF As Long

  RowMaxColB = Cells(Rows.Count, "B").End(xlUp).Row
  RowMaxColF = Cells(Rows.Count, "F").End(xlUp).Row

我同意Siddharth的观点,在这种情况下,Find似乎是最好的方法。然而,你应该看看我的回答,一个不同的问题。它包括一个宏,该宏演示了查找最后一行和最后一列的方法选择,并显示了它们失败的情况。

当我对通过串属性创建的对象类型感到困惑时,我会使用此技术

在Excel的Visual Basic编辑器中,如果您没有希望以这种方式使用的现有模块,请创建一个新模块。如果在Project Explorer中选择该模块并单击F4,则可以将该模块的名称更改为

键入或复制:

Option Explicit
Sub TestA()

End Sub
我总是用Option Explicit启动模块。在VBA帮助中查找Option Explicit,它将告诉您为什么这是一个好主意

我还创建了一个空的子程序,我将在其中键入一些语句

开始键入一条新语句,以便:

Sub TestA()

  Debug.Print Range("B:B").

End Sub
在新行末尾键入句点时,弹出窗口将显示可用的方法和属性。此列表将按预期显示范围的所有方法和属性。键入地址或从列表中选择地址以获取:

Sub TestA()

  Debug.Print Range("B:B").Address

End Sub
单击F5以运行t 他的宏和以下内容将出现在即时窗口中:

$B:$B
这是B列中所有行的地址,这是您所期望的

现在向宏中添加两个进一步的语句:

  Debug.Print Range("F:F").Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Count
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count
再次运行此宏,您将获得:

$B:$B
$F:$F
$B:$B,$F:$F
这也是人们所期望的

现在添加:

  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count.
出现的弹出窗口将保持不变,因为Range.Rows仍然是一个范围

通过添加或选择地址完成语句,然后再次运行宏以获取:

$B:$B
$F:$F
$B:$B,$F:$F
$B:$B,$F:$F
这可能不是你所期望的,但想想看$B:$B,$F:$F是B列和F列中的所有行,因此添加属性行不会更改地址

现在将以下语句添加到宏:

  Debug.Print Range("F:F").Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Address
  Debug.Print Union(Range("B:B"), Range("F:F")).Count
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count
运行宏,这些语句将分别输出一个整数。我正在使用Excel 2003,因此我得到:

 131072 
 65536 
如果您使用的是更高版本的Excel,则会得到更大的整数。第二个整数是Excel版本工作表中的行数。第一个整数是Excel版本工作表中两列中的单元格数

现在添加:

  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.
  Debug.Print Union(Range("B:B"), Range("F:F")).Rows.Count.
键入最后一个句点时,不会出现弹出窗口,因为整数没有可以通过这种方式选择的方法或属性。方法EndxlUp对一个范围进行操作;它不是Count的属性,这就是为什么会得到无效的限定符

将属性串在一起时,很容易让自己感到困惑。就我个人而言,我避免串接属性,因为即使它运行得更快,我也需要更长的时间来理解和调试。在某些情况下,最小化运行时间是首要任务,但这是其中之一吗?你用这种方法浪费了多少时间

考虑:

  Dim Rng1 As Range
  Dim Rng2 As Range
  Dim Rng3 As Range
  Dim RowMax As Long

  Set Rng1 = Range("B:B")
  Set Rng2 = Range("F:F")
  Set Rng3 = Union(Rng1, Rng2)
  RowMax = Rng3.Count

  Debug.Print RowMax

  Debug.Print Rng3.Find("*", Range("B1"), xlValues, xlWhole, xlByRows, xlPrevious).Row
Sub TestB()

  With Worksheets("Sheet1")
    .Range("A1").Value = "FIRST"
  End With

End Sub
  Dim Rng1 As Range

  With Worksheets("Sheet2")
    Set Rng1 = Union(Range("A:A"), Range("C:D"), Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
    Set Rng1 = Union(.Range("A:A"), .Range("C:D"), .Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
  End With
您不需要RowMax,但我已经包含了它,所以您完全清楚Rng3.Count返回的是什么。我也去了OTT的范围。我很乐意输入:Set Rng3=UnionRangeB:B,RangeF:F,因为我觉得这很容易理解

方法EndxlUp对单元格进行操作。MultiCellRange.EndxlUp.Row是有效的语法,但我无法让它返回有用的信息。如果要使用.EndxlUp,请考虑:

  Dim RowMaxColB As Long
  Dim RowMaxColF As Long

  RowMaxColB = Cells(Rows.Count, "B").End(xlUp).Row
  RowMaxColF = Cells(Rows.Count, "F").End(xlUp).Row

我同意Siddharth的观点,在这种情况下,Find似乎是最好的方法。然而,你应该看看我的回答,一个不同的问题。它包括一个宏,该宏演示了查找最后一行和最后一列的方法选择,并显示了它们失败的情况。

您还没有提出这是一个答案的问题。有关您要求的答案,请参阅。你的代码运行正常,所以我怀疑你是否知道它是坏的VBA

从顶部的注释来看,我假设这段代码是由宏记录器创建的。宏记录器输出语法正确的代码,但代码质量较差。代码质量差的部分原因至少是因为在键入时记录了语句。录音员不知道你的目标。如果光标位于单元格A1中,您按向右键,记录器将选择B1,因为屏幕上会出现这种情况。在VBA中,有些情况下Select是一种有用的方法,但很少使用

记录器也会对活动工作表进行操作,这很少是一个好主意。如果启动此宏时错误的工作表处于活动状态,则将销毁该工作表并删除13列

我假设您只打开了一个工作簿,因此我可以假设活动工作簿是必需的工作簿。处理多个工作簿只是稍微复杂一点,但我宁愿忽略这一复杂性

考虑:

  Dim Rng1 As Range
  Dim Rng2 As Range
  Dim Rng3 As Range
  Dim RowMax As Long

  Set Rng1 = Range("B:B")
  Set Rng2 = Range("F:F")
  Set Rng3 = Union(Rng1, Rng2)
  RowMax = Rng3.Count

  Debug.Print RowMax

  Debug.Print Rng3.Find("*", Range("B1"), xlValues, xlWhole, xlByRows, xlPrevious).Row
Sub TestB()

  With Worksheets("Sheet1")
    .Range("A1").Value = "FIRST"
  End With

End Sub
  Dim Rng1 As Range

  With Worksheets("Sheet2")
    Set Rng1 = Union(Range("A:A"), Range("C:D"), Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
    Set Rng1 = Union(.Range("A:A"), .Range("C:D"), .Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
  End With
工作表Sheets1说明此代码将在活动工作簿中名为Sheet1的工作表上操作。End With终止With语句

您可以嵌套语句:

  With Worksheets("Sheet1")
    With .Range("A1")
      .Value = "FIRST"
      .Font.Bold = True
      .Font.Color = RGB(0, 255, 255)
    End With
  End With
.RangeA1开头的时段表示.RangeA1在当前工作表Sheets1中运行。如果省略该句点,RangeA1将在活动工作表上运行

.值开头的时段表示它将在工作表Sheets1中范围为A1的电流上运行。如果省略该周期,则该值对活动单元格起作用

With语句的使用使代码更加紧凑和清晰。但是,必须包含句点。考虑:

  Dim Rng1 As Range

  With Worksheets("Sheet2")
    Set Rng1 = Union(Range("A:A"), Range("C:D"), Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
    Set Rng1 = Union(.Range("A:A"), .Range("C:D"), .Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
  End With
如果活动工作表为Sheet1,则输出为:

$A:$A,$C:$D,$F:$G
Sheet1
$A:$A,$C:$D,$F:$G
Sheet2
范围地址看起来相同,但适用于不同的工作表

您可以用以下代码替换大量代码:

  With Worksheets("Sheet1")
    .Range("A1").Value = "FIRST"
    .Range("B1").Value = "LAST"
    .Range("C1").Value = "G"
    .Range("D1").Value = "PHONE"
    .Range("E1").Value = "ADDRESS"
    .Range("F1").Value = "CITY"
    .Range("G1").Value = "STATE"
    .Range("H1").Value = "ZIP"
    .Range("I1").Value = "MONTH"
    .Range("J1").Value = "YEAR"
  End With
你也可以写:

  With Worksheets("Sheet1")
    .Range("A1:J1").Value = Array("FIRST", "LAST", "G", "PHONE", "ADDRESS", _
                                  "CITY", "STATE", "ZIP", "MONTH", "YEAR")
 End With
这个VBA要先进得多。可以将值从工作表范围复制到数组,也可以从数组复制到工作表范围。这里有许多问题和答案可以探索这一能力,我不会在这里重复这些答案。这只是一个演示,如果您感兴趣,可以在以后进行探索

我不喜欢你正在做的事。在您的第一个语句中,您删除了一些列,使B列成为A列,R列成为I列。然后,您可以更改它们中的列标题 新职位。既然只移动数据,为什么需要更改列标题?更重要的是,九个月后,有人将添加一列或重新排列现有列。你的代码将继续运行,你的名字将是泥浆

我更喜欢这样的:

  With Worksheets("Sheet1")
    If .Range("B1").Value = "FIRST" And .Range("C1").Value = "LAST" And _
       .Range("D1").Value = "G" And .Range("E1").Value = "PHONE" And _
       .Range("G1").Value = "ADDRESS" And .Range("H1").Value = "CITY" And _
       .Range("I1").Value = "STATE" And .Range("J1").Value = "ZIP" And _
       .Range("R1").Value = "MONTH" And .Range("W1").Value = "YEAR" Then
      ' Column headings as expected.  Continue with macro.
    Else
      Call MsgBox("I am sorry but I cannot proceed because the column " & _
                  "headings are not as I expected.", vbOKOnly)
      Exit Sub
    End If
  End With

如果您的代码要求工作表采用特定的格式,并且该格式可能会随着时间的推移而改变,请检查该格式。

您还没有提出这是答案的问题。有关您要求的答案,请参阅。你的代码运行正常,所以我怀疑你是否知道它是坏的VBA

从顶部的注释来看,我假设这段代码是由宏记录器创建的。宏记录器输出语法正确的代码,但代码质量较差。代码质量差的部分原因至少是因为在键入时记录了语句。录音员不知道你的目标。如果光标位于单元格A1中,您按向右键,记录器将选择B1,因为屏幕上会出现这种情况。在VBA中,有些情况下Select是一种有用的方法,但很少使用

记录器也会对活动工作表进行操作,这很少是一个好主意。如果启动此宏时错误的工作表处于活动状态,则将销毁该工作表并删除13列

我假设您只打开了一个工作簿,因此我可以假设活动工作簿是必需的工作簿。处理多个工作簿只是稍微复杂一点,但我宁愿忽略这一复杂性

考虑:

  Dim Rng1 As Range
  Dim Rng2 As Range
  Dim Rng3 As Range
  Dim RowMax As Long

  Set Rng1 = Range("B:B")
  Set Rng2 = Range("F:F")
  Set Rng3 = Union(Rng1, Rng2)
  RowMax = Rng3.Count

  Debug.Print RowMax

  Debug.Print Rng3.Find("*", Range("B1"), xlValues, xlWhole, xlByRows, xlPrevious).Row
Sub TestB()

  With Worksheets("Sheet1")
    .Range("A1").Value = "FIRST"
  End With

End Sub
  Dim Rng1 As Range

  With Worksheets("Sheet2")
    Set Rng1 = Union(Range("A:A"), Range("C:D"), Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
    Set Rng1 = Union(.Range("A:A"), .Range("C:D"), .Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
  End With
工作表Sheets1说明此代码将在活动工作簿中名为Sheet1的工作表上操作。End With终止With语句

您可以嵌套语句:

  With Worksheets("Sheet1")
    With .Range("A1")
      .Value = "FIRST"
      .Font.Bold = True
      .Font.Color = RGB(0, 255, 255)
    End With
  End With
.RangeA1开头的时段表示.RangeA1在当前工作表Sheets1中运行。如果省略该句点,RangeA1将在活动工作表上运行

.值开头的时段表示它将在工作表Sheets1中范围为A1的电流上运行。如果省略该周期,则该值对活动单元格起作用

With语句的使用使代码更加紧凑和清晰。但是,必须包含句点。考虑:

  Dim Rng1 As Range

  With Worksheets("Sheet2")
    Set Rng1 = Union(Range("A:A"), Range("C:D"), Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
    Set Rng1 = Union(.Range("A:A"), .Range("C:D"), .Range("F:G"))
    Debug.Print Rng1.Address
    Debug.Print Rng1.Worksheet.Name
  End With
如果活动工作表为Sheet1,则输出为:

$A:$A,$C:$D,$F:$G
Sheet1
$A:$A,$C:$D,$F:$G
Sheet2
范围地址看起来相同,但适用于不同的工作表

您可以用以下代码替换大量代码:

  With Worksheets("Sheet1")
    .Range("A1").Value = "FIRST"
    .Range("B1").Value = "LAST"
    .Range("C1").Value = "G"
    .Range("D1").Value = "PHONE"
    .Range("E1").Value = "ADDRESS"
    .Range("F1").Value = "CITY"
    .Range("G1").Value = "STATE"
    .Range("H1").Value = "ZIP"
    .Range("I1").Value = "MONTH"
    .Range("J1").Value = "YEAR"
  End With
你也可以写:

  With Worksheets("Sheet1")
    .Range("A1:J1").Value = Array("FIRST", "LAST", "G", "PHONE", "ADDRESS", _
                                  "CITY", "STATE", "ZIP", "MONTH", "YEAR")
 End With
这个VBA要先进得多。可以将值从工作表范围复制到数组,也可以从数组复制到工作表范围。这里有许多问题和答案可以探索这一能力,我不会在这里重复这些答案。这只是一个演示,如果您感兴趣,可以在以后进行探索

我不喜欢你正在做的事。在第一个语句中,删除一些列,使B列成为A列,R列成为I列。然后更改列标题的新位置。既然只移动数据,为什么需要更改列标题?更重要的是,九个月后,有人将添加一列或重新排列现有列。你的代码将继续运行,你的名字将是泥浆

我更喜欢这样的:

  With Worksheets("Sheet1")
    If .Range("B1").Value = "FIRST" And .Range("C1").Value = "LAST" And _
       .Range("D1").Value = "G" And .Range("E1").Value = "PHONE" And _
       .Range("G1").Value = "ADDRESS" And .Range("H1").Value = "CITY" And _
       .Range("I1").Value = "STATE" And .Range("J1").Value = "ZIP" And _
       .Range("R1").Value = "MONTH" And .Range("W1").Value = "YEAR" Then
      ' Column headings as expected.  Continue with macro.
    Else
      Call MsgBox("I am sorry but I cannot proceed because the column " & _
                  "headings are not as I expected.", vbOKOnly)
      Exit Sub
    End If
  End With

如果代码要求工作表采用特定格式,并且该格式可能会随时间而更改,请检查该格式。

用于查找多列中的最后一行。也可用于查找多列中的最后一行。还有@L42。谢谢自从我第一次学习Excel VBA可能已经有10多年了,但我仍然记得我对对象模型是多么的困惑。感谢大家在这里的贡献。托尼,我非常感谢你花时间分享你的知识。糟糕的代码…哈哈,我有很多东西要学。谢谢你的帮助!“这里有很多东西需要吸收。”托马斯。我怀疑我的第一个宏是否有这么大的雄心壮志或这么好,所以请不要难过。@L42。谢谢自从我第一次学习Excel VBA可能已经有10多年了,但我仍然记得我对对象模型是多么的困惑。感谢大家在这里的贡献。托尼,我非常感谢你花时间分享你的知识。糟糕的代码…哈哈,我有很多东西要学。谢谢你的帮助!“这里有很多东西需要吸收。”托马斯。我怀疑我的第一个宏是否有这么大的雄心壮志或这么好,所以请不要难过。