Excel VBA新增:编译错误无效限定符。
此代码旨在获取原始数据的电子表格,省略几列,并重新设置剩余数据的格式。我欢迎对代码的任何和所有批评,因为我是VBA新手,什么都不知道。关键问题是代码的末尾,下面用astrics表示。这就是出现编译错误的地方:出现无效限定符。我试图将格式应用于B列和F列,但我只希望它一直到日期的最后一行。最后一行数据将随工作表的不同而变化 触发错误时,调试器将突出显示字数 提前感谢你的帮助Excel VBA新增:编译错误无效限定符。,excel,vba,Excel,Vba,此代码旨在获取原始数据的电子表格,省略几列,并重新设置剩余数据的格式。我欢迎对代码的任何和所有批评,因为我是VBA新手,什么都不知道。关键问题是代码的末尾,下面用astrics表示。这就是出现编译错误的地方:出现无效限定符。我试图将格式应用于B列和F列,但我只希望它一直到日期的最后一行。最后一行数据将随工作表的不同而变化 触发错误时,调试器将突出显示字数 提前感谢你的帮助 Sub Macro2() ' ' Macro2 Macro ' Union(Range("A:A"), Range("F: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多年了,但我仍然记得我对对象模型是多么的困惑。感谢大家在这里的贡献。托尼,我非常感谢你花时间分享你的知识。糟糕的代码…哈哈,我有很多东西要学。谢谢你的帮助!“这里有很多东西需要吸收。”托马斯。我怀疑我的第一个宏是否有这么大的雄心壮志或这么好,所以请不要难过。