此代码旨在获取原始数据的电子表格,省略多个列,并重新格式化剩余的内容。我欢迎对代码的任何批评,因为我是VBA的新手并且一无所知。关键问题是在下面用astriscs指示的行代码的末尾。这是出现“编译错误:无效限定符”的地方。我正在尝试将格式应用于列B和F,但我只希望它到最后一行日期。最后一行数据因工作表而异。
当触发错误时,调试器会突出显示“count”一词。
提前感谢您的帮助。
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
答案 0 :(得分:5)
当我对通过字符串属性创建的对象类型感到困惑时,我使用了这种技术。
在Excel的Visual Basic编辑器中,如果您没有希望以这种方式使用的现有模块,请创建一个新模块。如果在Project Explorer中选择模块并单击F4,则可以将模块的名称更改为“Experiments”。
输入或复制:
Option Explicit
Sub TestA()
End Sub
我始终使用Option Explicit
启动我的模块。在VBA帮助中查看Option Explicit
,它会告诉您为什么这是个好主意。
我还创建了一个空的子例程,我将在其中键入一些语句。
开始输入新语句,以便:
Sub TestA()
Debug.Print Range("B:B").
End Sub
当您在此新行末尾键入句点时,弹出窗口将显示可用的方法和属性。该列表将按预期显示Range的所有方法和属性。输入“地址”或从列表中选择地址以获取:
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
再次运行此宏,您将获得:
$B:$B
$F:$F
$B:$B,$F:$F
这也是预期的结果。
现在添加:
Debug.Print Union(Range("B:B"), Range("F:F")).Rows.
出现的弹出窗口将保持不变,因为Range.Rows
仍然是一个范围。
通过添加或选择“地址”完成声明并再次运行宏以获取:
$B:$B
$F:$F
$B:$B,$F:$F
$B:$B,$F:$F
这可能不是您的预期,但请考虑一下。 $B:$B,$F:$F
是B列和F列中的所有行,因此添加属性Rows
不会更改地址。
现在将以下语句添加到宏:
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.Count.
键入最后一个句点时,不会出现弹出窗口,因为整数没有可以通过这种方式选择的方法或属性。方法.End(xlUp)
对范围进行操作;它不是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
您不需要RowMax
但我已将其包含在内,因此您绝对清楚Rng3.Count
返回的内容。我也用范围去了OTT。我很乐意输入:Set Rng3 = Union(Range("B:B"), Range("F:F"))
因为我觉得它很容易理解。
方法.End(xlUp)
对单元格进行操作。 MultiCellRange.End(xlUp).Row
是有效的语法,但我不能让它返回有用的信息。如果您想使用.End(xlUp)
,请考虑:
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
似乎是这种情况下最好的方法。但是,您应该将我的这个答案https://stackoverflow.com/a/20849875/973283看一个不同的问题。它包含一个宏,它演示了一系列查找最后行和列的方法,并显示了它们失败的情况。
答案 1 :(得分:1)
您还没有问过这是一个答案的问题。有关您要求的答案,请参阅Requested answer。你的代码有效,所以我怀疑你知道VBA是坏的。
从顶部的评论中,我假设此代码是由Macro Recorder创建的。宏记录器输出语法正确的代码,但代码很差。代码不好的部分原因至少是在键入时记录语句。记录器不知道你的目标。如果光标位于单元格A1中并按右,则记录器将选择B1,因为这是屏幕上发生的情况。在VBA中可能存在Select
是一种有用的方法的情况,但它们很少见。
记录器也在活动工作表上运行,这很少是一个好主意。如果启动此宏时错误的工作表处于活动状态,则会删除13列,并将其删除。
我假设您只打开了一个工作簿,因此我可以假设活动工作簿是必需的工作簿。处理多个工作簿只是稍微复杂一些,但我宁愿忽略这种复杂性。
考虑:
Sub TestB()
With Worksheets("Sheet1")
.Range("A1").Value = "FIRST"
End With
End Sub
With Worksheets("Sheet1")
声明此代码用于在活动工作簿的名为“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
.Range("A1")
个州.Range("A1")
开头的时段是在当前的Worksheets("Sheet1")
范围内运行。如果我省略该期间,Range("A1")
将在活动工作表上运行。
.Value
开头的句号表示它将在Range("A1")
内的Worksheets("Sheet1")
上运行。如果我省略该期间,Value
将对活动单元格进行操作。
使用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
如果您的代码要求工作表采用特定格式,并且该格式可能会随时间发生变化,请检查该格式。