我在与VBA斗争 - 我倾向于写作好像我是宏录制器,因此编写非常丑陋的宏并最终使事情变得比需要的复杂得多。
您是否可以查看并帮助确定一些效率?我想学习编写好的代码,但需要比较和对比,而不是看其他人的例子。
Sub ColumnSearch()
'Filepath variables - the filename changes daily but always contains the name notifications, this seemed to be the easiest method
Dim filepath As String
filepath = ActiveWorkbook.Path + "\"
Application.ScreenUpdating = False
Dim file As String
Dim fullfilepath As String
file = Dir$(filepath & "*Notifications*" & ".*")
fullfilepath = filepath & file
Application.EnableEvents = False
Workbooks.Open (fullfilepath)
Windows(file).Activate
Application.EnableEvents = True
'variables set as string and range respetively
Dim strDoN As String, strOffice As String, strARN As String, strPIN As String, strAN As String, strAT As String, strSoS As String
Dim rngDoN As Range, rngOffice As Range, rngARN As Range, rngPIN As Range, rngAN As Range, rngAT As Range, rngSoS As Range
Dim rng2DoN As Range, rng2Office As Range, rng2ARN As Range, rng2PIN As Range, rng2AN As Range, rng2AT As Range, rng2SoS As Range
Dim myRange As Range
Dim NumCols, i As Integer
'str variables set as the text in row 1 (title cells)
strDoN = "Date of Notification"
strOffice = "Office Centre"
strARN = "Appeal Reference Number"
strPIN = "PIN"
strAN = "Appellant Name"
strAT = "Appeal Type"
strSoS = "SoS Decision Date"
Sheets("New Appeals").Activate
'For loop to find the address of the strings above
For i = 1 To 11
Select Case Cells(1, i).Value
Case strDoN
Set rngDoN = Cells(1, i) '
Case strOffice
Set rngOffice = Cells(1, i)
Case strARN
Set rngARN = Cells(1, i)
Case strPIN
Set rngPIN = Cells(1, i)
Case strAN
Set rngAN = Cells(1, i)
Case strAT
Set rngAT = Cells(1, i)
Case strSoS
Set rngSoS = Cells(1, i)
Case Else
'no match - do nothing
End Select
Next i
'Identify the count of cells to be copied from one sheet to the other
RowLast = Cells(Rows.Count, rngOffice.Column).End(xlUp).Row
Cells(RowLast - 1, rngOffice.Column).Select
Range(Selection, Selection.End(xlUp)).Offset(1, 0).Copy
'activate the other workbook, run the same search for loop but with rng2 being set (rng and rng2 can be different as there are sometimes extra columns that are not required
Workbooks("Book2.xlsm").Activate
Sheets("New Appeals").Select
For i = 1 To 11
Select Case Cells(1, i).Value
Case strDoN
Set rng2DoN = Cells(1, i) '<~~ set the range object to this cell
Case strOffice
Set rng2Office = Cells(1, i)
Case strARN
Set rng2ARN = Cells(1, i)
Case strPIN
Set rng2PIN = Cells(1, i)
Case strAN
Set rng2AN = Cells(1, i)
Case strAT
Set rng2AT = Cells(1, i)
Case strSoS
Set rng2SoS = Cells(1, i)
Case Else
'no match - do nothing
End Select
Next i
Dim RowLast2 As Long
'find the last cell that was updated (every day the list will grow, it has to be pasted at the bottom of the last update)
RowLast2 = Cells(Rows.Count, rng2Office.Column).End(xlUp).Row
Cells(RowLast2, rng2Office.Column).Offset(1, 0).Select
Selection.PasteSpecial
Workbooks(file).Activate
Sheets("New Appeals").Select
'start from scratch again but with the next variable etc
RowLast = Cells(Rows.Count, rngARN.Column).End(xlUp).Row
Cells(RowLast - 1, rngARN.Column).Select
Range(Selection, Selection.End(xlUp)).Offset(1, 0).Copy
Workbooks("Book2.xlsm").Activate
Sheets("New Appeals").Select
RowLast2 = Cells(Rows.Count, rng2ARN.Column).End(xlUp).Row
Cells(RowLast2, rng2ARN.Column).Offset(1, 0).Select
Selection.PasteSpecial
Workbooks(file).Activate
Sheets("New Appeals").Select
End Sub
如果这是不适当的,请告诉我,如果需要,我会删除它!
答案 0 :(得分:4)
我会考虑以下事项:
VBA
CamelCase很常见。另外,在变量名中加上对象类型是很常见的,即strDoN as String
。如果您这样做,请确保您无处不在(因此filepath
应为strFilePath
)。有关命名约定,请参阅here。Dim
语句放在子例程的开头。Select
和Activate
。Dim
- ing :当您执行Dim NumCols, i as Integer
时,实际上Dim NumCols as Variant, i as Integer
。如果您希望它们都是整数,请使用Dim Numcols as Integer, i as Integer
。此外,更喜欢Long
到Integer
。Option Explicit
置于您的模块/工作表之上。这意味着应该首先声明使用的每个变量(使用Dim
语句)。这对于避免来自拼写错误的错误以及将所有变量定义在一个位置非常有用。您的某些变量(例如RowLast
)现在未明确定义,并且属于Variant
类型,而其类型可能更具体。Sheets("New Appeals").Activate
,New Appeals
将起作用,但如果用户更改了名称,它将会中断。 Use the sheet's ID instead。同样,在您的代码中,您将字符串变量分配给硬编码字符串("Date of Notification"
等)。如果您在工作表中设计一个区域,每次都可以从中提取数据,这样会更安全。Case
s :最佳解决方案是使用Dictionary
个对象。它更优雅,代码更简洁。一个例子是here。Selection
方法。此外,并不总是需要激活工作表以便复制/粘贴。 Range
对象可以做有用的东西(搜索,特殊单元等)。 Check it out。Range/Cells
对象的全名,以避免错误。相关SO帖子here。Excel
和VBA
之间传递数据可能非常耗时。一个好的做法是将excel数据传递给Variant
数组,执行任何处理,然后将它们转储回excel。 This是一本很好的读物。With
块:当您多次引用对象的属性/方法时,它会增强可读性。示例here。我希望这会有所帮助。这并不是一个详尽的清单,但从一开始就可能有用。快乐的编码!