GomezAddamz
Technical User
Hey forum! I've written a macro for Excel 2010 for work. It's perfectly functional. It does everything I need it to and it doesn't have any problems. It is, however, clunky. At least it seems that way to me. I'm pretty new to VBA (for Excel in particular), and am interested in getting better. I was hoping to use this example as an opportunity to improve. I'd appreciate it if you guys could take a look at this and let me know what you think. Any and all tips, ideas, feedback, etc. is greatly appreciated.
This is a macro that will update an Excel file (current data) based on the contents of a semi-colon delimited text file (new data). If a current entry is not in the new data, it can be marked as complete. If a current entry is in the new data, it can be ignored. Here's how the code is structured.
Part 1 loads new data and initialize variables. 'j' is the index of the last 'Completed' entry, which is stored on its own sheet.
Part 2 moves 'Completed' entries out of current data. Column 'E' contains a unique identifier which is used to compare the current data to the new data. This loop takes every entry in current data and looks for it in new data. If the current data is found in the new data, it moves on to the next entry. If the data is not found, it moves it to the Completed sheet. 'i' is the index for the current data, which begins on the second row, and 'r' is the index for the new data, which begins on the fifth row.
Part 3 ignores new data that is already in current data. Basically it does the reverse of the last section. This time, it takes every entry in new data and compares it to the current data. If the new data already exists in the current data, the entry is discarded. Otherwise, it is left alone.
Part 4 adds the new data to the current data, and part 5 closes files and displays updated results.
I had the relevant sections of code beneath their descriptions, but that looked a bit weird in the preview. I've marked the different parts in the code below, but they shouldn't be too hard to associate. As you can see, I've used a lot of Do Until loops. I started by using For loops, but then I needed to know how many iterations before entering the loop, as opposed to the more dynamic nature of the Do loop. Also, I haven't really found a good way to find the last entry on a worksheet.
We're going to have about 50 different spreadsheets that will have this macro. There should not be a situation where there is a lot of data (1000+ entries) in either the current or new data. As I say, as it is, it's working for what it needs to do, but from a coding/standards standpoint, I'd like to know what I could do to make it cleaner and maybe break some bad habits before they form. Let me know if you have any questions. Thanks!
This is a macro that will update an Excel file (current data) based on the contents of a semi-colon delimited text file (new data). If a current entry is not in the new data, it can be marked as complete. If a current entry is in the new data, it can be ignored. Here's how the code is structured.
Part 1 loads new data and initialize variables. 'j' is the index of the last 'Completed' entry, which is stored on its own sheet.
Part 2 moves 'Completed' entries out of current data. Column 'E' contains a unique identifier which is used to compare the current data to the new data. This loop takes every entry in current data and looks for it in new data. If the current data is found in the new data, it moves on to the next entry. If the data is not found, it moves it to the Completed sheet. 'i' is the index for the current data, which begins on the second row, and 'r' is the index for the new data, which begins on the fifth row.
Part 3 ignores new data that is already in current data. Basically it does the reverse of the last section. This time, it takes every entry in new data and compares it to the current data. If the new data already exists in the current data, the entry is discarded. Otherwise, it is left alone.
Part 4 adds the new data to the current data, and part 5 closes files and displays updated results.
I had the relevant sections of code beneath their descriptions, but that looked a bit weird in the preview. I've marked the different parts in the code below, but they shouldn't be too hard to associate. As you can see, I've used a lot of Do Until loops. I started by using For loops, but then I needed to know how many iterations before entering the loop, as opposed to the more dynamic nature of the Do loop. Also, I haven't really found a good way to find the last entry on a worksheet.
We're going to have about 50 different spreadsheets that will have this macro. There should not be a situation where there is a lot of data (1000+ entries) in either the current or new data. As I say, as it is, it's working for what it needs to do, but from a coding/standards standpoint, I'd like to know what I could do to make it cleaner and maybe break some bad habits before they form. Let me know if you have any questions. Thanks!
Code:
Sub UpdateReport()
'Updates Excel spreadsheet based on imported text file
Application.ScreenUpdating = False
'Part 1: Initialize variables
dups = 0
dels = 0
adds = 0
recs = 0
'Set filepaths for new and current workbooks
currBook = Application.ActiveWorkbook.Name
openFile = Application.GetOpenFilename("All Files (*.*),*.*,Text Files (*.txt), *.txt", 2)
If openFile = False Then
MsgBox ("Update Failed. File may be in use.")
Exit Sub
End If
Workbooks.OpenText Filename:=openFile, DataType:=xlDelimited, Semicolon:=True
newBook = Application.ActiveWorkbook.Name
'Find the last completed entry
j = 1
Do Until Workbooks(currBook).Sheets(2).Range("E" & j).Value = ""
j = j + 1
Loop
'Part 2: Update current data based on new data
i = 2
fin = Workbooks(currBook).Sheets(1).Range("E2").Value
Do Until fin = ""
found = False
r = 5
dataCells = Workbooks(newBook).Sheets(1).Range("E5").Value
Do Until dataCells = ""
If dataCells = fin Then
found = True
Exit Do
End If
r = r + 1
dataCells = Workbooks(newBook).Sheets(1).Range("E" & r).Value
Loop
If found Then
i = i + 1
fin = Workbooks(currBook).Sheets(1).Range("E" & i).Value
Else
Workbooks(currBook).Sheets(2).Range("E" & j).EntireRow.Value = Workbooks(currBook).Sheets(1).Range("E" & i).EntireRow.Value
Workbooks(currBook).Sheets(1).Range("E" & i).EntireRow.Delete
Workbooks(currBook).Sheets(2).Range("N" & j).Value = Date
j = j + 1
dels = dels + 1
fin = Workbooks(currBook).Sheets(1).Range("E" & i).Value
End If
Loop
'Part 3: Remove new data that is already in current data
r = 5
dataCell = Workbooks(newBook).Sheets(1).Range("E5").Value
Do Until dataCell = ""
recs = recs + 1
i = 2
fin = Workbooks(currBook).Sheets(1).Range("E" & i).Value
Do Until fin = ""
If dataCell = fin Then
Workbooks(newBook).Sheets(1).Range("E" & r).EntireRow.Delete
dups = dups + 1
r = r - 1
Exit Do
End If
i = i + 1
fin = Workbooks(currBook).Sheets(1).Range("E" & i).Value
Loop
r = r + 1
dataCell = Workbooks(newBook).Sheets(1).Range("E" & r)
Loop
'Part 4: Add new data to current data
i = 1
Do Until Workbooks(currBook).Sheets(1).Range("E" & i).Value = ""
i = i + 1
Loop
r = 5
Do Until Workbooks(newBook).Sheets(1).Range("E" & r).Value = ""
Workbooks(currBook).Sheets(1).Range("E" & i).EntireRow.Value = Workbooks(newBook).Sheets(1).Range("E" & r).EntireRow.Value
Workbooks(currBook).Sheets(1).Range("M" & i).Value = Date
i = i + 1
r = r + 1
adds = adds + 1
Loop
'Part 5: Clean up and report
Application.ActiveWorkbook.Close (False)
Application.ScreenUpdating = True
junk = MsgBox("" & recs & " records processed. " & vbNewLine & _
adds & " records added," & vbNewLine & _
dels & " records removed," & vbNewLine & _
dups & " records omitted.", vbOKOnly, "Update Results")
End Sub