VBA code meant for a many to one translation of import rows











up vote
3
down vote

favorite












Background: End users wanted to automate the process of taking information out of our CRM software (in the form of a csv), and then process it into something more usable for their purposes. Ended up not getting used, but I did manage to make it run/work on old data.



The following code expects an import of values to be placed in a sheet labeled "Import", each row of the import is associated with a specific location that has been inspected, but there are multiple rows per location (different comments, and information for the location).



The code is meant to take these multiple rows, and create an output with only one row per location, while concatenating the information that isn't duplicated in the import rows.



Wanted to see how many pitfalls I've fallen into, I've taken college coursework with programming, but no real guidance in industry (learned a great deal through trial/error when asked to make something at work).



Code does run, but I'm particularly interested in knowing whether my use of an array is really bad practice or not. I use a similar structure for a lot of the VBA code I make that needs to deal with import data (I don't know of a better way to manipulate the data, leaving it in the sheets ends up being excessively slow on larger sets of data).



Sub ProcessData()

Dim Imp_Sheet As Worksheet
Set Imp_Sheet = Sheets("Import")
Dim Unique_Sheet As Worksheet
Set Unique_Sheet = Sheets("UniqueVals")
Dim Out_Sheet As Worksheet
Set Out_Sheet = Sheets("Output")

'Clear unique value sheet
Unique_Sheet.Cells.Clear

'Copy up to 3000 locations from the import sheet.
Imp_Sheet.Range("C1:C3000").Copy
Unique_Sheet.Paste (Unique_Sheet.Cells(1, 1))
'Remove duplicate locations
Unique_Sheet.Range("A1:A3000").RemoveDuplicates Columns:=(1), Header:=xlYes

'Find number of inspections(Could include duplicate inspections that I don't want)
Dim Inspection_Total As Long: Inspection_Total = Find_End(Unique_Sheet.Name)

For i = 2 To Inspection_Total
'Check if it's found the end of the unique value list
If (Unique_Sheet.Cells(i, 1).Value = "") Then
Exit For
End If
'give each unique value a number for future reference
Unique_Sheet.Cells(i, 2).Value = i - 1
Next i

Unique_Sheet.Cells(1, 2).Value = i - 2
'Change inspection total to be the actual number of inspections
Inspection_Total = i - 2

Dim Import_Total: Import_Total = Find_End(Imp_Sheet.Name)

'Prepare array to load import values into.
Dim Imp_Arr() As Variant
'0 = location, 1= city, 2= st, 3=date site set, 4=pre-ins date, 5= mod name, 6= mod title, 7 = summary
ReDim Imp_Arr(Inspection_Total, 7)

'Walk through import sheet, for reach row, compare to the list of unique locations (to find where each row belongs)
For i = 2 To Import_Total
For x = 2 To Unique_Sheet.Cells(1, 2) + 1
If (Imp_Sheet.Cells(i, 3) = Unique_Sheet.Cells(x, 1)) Then
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)
'Comments on a specific location need to be on one row, this accomplishes that
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) = Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) & Imp_Sheet.Cells(i, 10) & " " & Imp_Sheet.Cells(i, 11) & " " & Imp_Sheet.Cells(i, 12) & ";" & Chr(10)
End If
Next x
Next i

'Output one row for each location.
For i = 0 To Inspection_Total

For Z = 0 To 7
'
Out_Sheet.Cells(i + 2, Z + 1).Value = Imp_Arr(i, Z)

Next Z

Next i

End Sub









share|improve this question
















bumped to the homepage by Community 4 hours ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • What is the reason for processing exactly 3000 rows in this Sub?
    – Doc Brown
    Oct 5 '17 at 17:50












  • @doc-brown I didn't know how many they would be attempting to run, but was fairly confident that 3000 would be an order of magnitude more than the likely scenario (using previous year's data for testing purposes was something like ~300 import lines).
    – Jack Of All Trades 234
    Oct 5 '17 at 18:13










  • I typically avoid such magic numbers in code. You can surely determine the used rows or cells in the input sheet, I guess. That will make your code more robust against future changes.
    – Doc Brown
    Oct 5 '17 at 18:54






  • 1




    It's best to use a Dictionary or some type of Collection when comparing unique values in two list. If you're not worried about clearing data not present in the imported data then you can simply write the whole array at one time to Sheets("UniqueVals"). Dynamic Ranges are preferred over static ones (e.g. Range("A1", Range("A" & Rows.Count).End(xlUp)) is better then Range("A1:A3000")).
    – user109261
    Oct 30 '17 at 5:54















up vote
3
down vote

favorite












Background: End users wanted to automate the process of taking information out of our CRM software (in the form of a csv), and then process it into something more usable for their purposes. Ended up not getting used, but I did manage to make it run/work on old data.



The following code expects an import of values to be placed in a sheet labeled "Import", each row of the import is associated with a specific location that has been inspected, but there are multiple rows per location (different comments, and information for the location).



The code is meant to take these multiple rows, and create an output with only one row per location, while concatenating the information that isn't duplicated in the import rows.



Wanted to see how many pitfalls I've fallen into, I've taken college coursework with programming, but no real guidance in industry (learned a great deal through trial/error when asked to make something at work).



Code does run, but I'm particularly interested in knowing whether my use of an array is really bad practice or not. I use a similar structure for a lot of the VBA code I make that needs to deal with import data (I don't know of a better way to manipulate the data, leaving it in the sheets ends up being excessively slow on larger sets of data).



Sub ProcessData()

Dim Imp_Sheet As Worksheet
Set Imp_Sheet = Sheets("Import")
Dim Unique_Sheet As Worksheet
Set Unique_Sheet = Sheets("UniqueVals")
Dim Out_Sheet As Worksheet
Set Out_Sheet = Sheets("Output")

'Clear unique value sheet
Unique_Sheet.Cells.Clear

'Copy up to 3000 locations from the import sheet.
Imp_Sheet.Range("C1:C3000").Copy
Unique_Sheet.Paste (Unique_Sheet.Cells(1, 1))
'Remove duplicate locations
Unique_Sheet.Range("A1:A3000").RemoveDuplicates Columns:=(1), Header:=xlYes

'Find number of inspections(Could include duplicate inspections that I don't want)
Dim Inspection_Total As Long: Inspection_Total = Find_End(Unique_Sheet.Name)

For i = 2 To Inspection_Total
'Check if it's found the end of the unique value list
If (Unique_Sheet.Cells(i, 1).Value = "") Then
Exit For
End If
'give each unique value a number for future reference
Unique_Sheet.Cells(i, 2).Value = i - 1
Next i

Unique_Sheet.Cells(1, 2).Value = i - 2
'Change inspection total to be the actual number of inspections
Inspection_Total = i - 2

Dim Import_Total: Import_Total = Find_End(Imp_Sheet.Name)

'Prepare array to load import values into.
Dim Imp_Arr() As Variant
'0 = location, 1= city, 2= st, 3=date site set, 4=pre-ins date, 5= mod name, 6= mod title, 7 = summary
ReDim Imp_Arr(Inspection_Total, 7)

'Walk through import sheet, for reach row, compare to the list of unique locations (to find where each row belongs)
For i = 2 To Import_Total
For x = 2 To Unique_Sheet.Cells(1, 2) + 1
If (Imp_Sheet.Cells(i, 3) = Unique_Sheet.Cells(x, 1)) Then
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)
'Comments on a specific location need to be on one row, this accomplishes that
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) = Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) & Imp_Sheet.Cells(i, 10) & " " & Imp_Sheet.Cells(i, 11) & " " & Imp_Sheet.Cells(i, 12) & ";" & Chr(10)
End If
Next x
Next i

'Output one row for each location.
For i = 0 To Inspection_Total

For Z = 0 To 7
'
Out_Sheet.Cells(i + 2, Z + 1).Value = Imp_Arr(i, Z)

Next Z

Next i

End Sub









share|improve this question
















bumped to the homepage by Community 4 hours ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • What is the reason for processing exactly 3000 rows in this Sub?
    – Doc Brown
    Oct 5 '17 at 17:50












  • @doc-brown I didn't know how many they would be attempting to run, but was fairly confident that 3000 would be an order of magnitude more than the likely scenario (using previous year's data for testing purposes was something like ~300 import lines).
    – Jack Of All Trades 234
    Oct 5 '17 at 18:13










  • I typically avoid such magic numbers in code. You can surely determine the used rows or cells in the input sheet, I guess. That will make your code more robust against future changes.
    – Doc Brown
    Oct 5 '17 at 18:54






  • 1




    It's best to use a Dictionary or some type of Collection when comparing unique values in two list. If you're not worried about clearing data not present in the imported data then you can simply write the whole array at one time to Sheets("UniqueVals"). Dynamic Ranges are preferred over static ones (e.g. Range("A1", Range("A" & Rows.Count).End(xlUp)) is better then Range("A1:A3000")).
    – user109261
    Oct 30 '17 at 5:54













up vote
3
down vote

favorite









up vote
3
down vote

favorite











Background: End users wanted to automate the process of taking information out of our CRM software (in the form of a csv), and then process it into something more usable for their purposes. Ended up not getting used, but I did manage to make it run/work on old data.



The following code expects an import of values to be placed in a sheet labeled "Import", each row of the import is associated with a specific location that has been inspected, but there are multiple rows per location (different comments, and information for the location).



The code is meant to take these multiple rows, and create an output with only one row per location, while concatenating the information that isn't duplicated in the import rows.



Wanted to see how many pitfalls I've fallen into, I've taken college coursework with programming, but no real guidance in industry (learned a great deal through trial/error when asked to make something at work).



Code does run, but I'm particularly interested in knowing whether my use of an array is really bad practice or not. I use a similar structure for a lot of the VBA code I make that needs to deal with import data (I don't know of a better way to manipulate the data, leaving it in the sheets ends up being excessively slow on larger sets of data).



Sub ProcessData()

Dim Imp_Sheet As Worksheet
Set Imp_Sheet = Sheets("Import")
Dim Unique_Sheet As Worksheet
Set Unique_Sheet = Sheets("UniqueVals")
Dim Out_Sheet As Worksheet
Set Out_Sheet = Sheets("Output")

'Clear unique value sheet
Unique_Sheet.Cells.Clear

'Copy up to 3000 locations from the import sheet.
Imp_Sheet.Range("C1:C3000").Copy
Unique_Sheet.Paste (Unique_Sheet.Cells(1, 1))
'Remove duplicate locations
Unique_Sheet.Range("A1:A3000").RemoveDuplicates Columns:=(1), Header:=xlYes

'Find number of inspections(Could include duplicate inspections that I don't want)
Dim Inspection_Total As Long: Inspection_Total = Find_End(Unique_Sheet.Name)

For i = 2 To Inspection_Total
'Check if it's found the end of the unique value list
If (Unique_Sheet.Cells(i, 1).Value = "") Then
Exit For
End If
'give each unique value a number for future reference
Unique_Sheet.Cells(i, 2).Value = i - 1
Next i

Unique_Sheet.Cells(1, 2).Value = i - 2
'Change inspection total to be the actual number of inspections
Inspection_Total = i - 2

Dim Import_Total: Import_Total = Find_End(Imp_Sheet.Name)

'Prepare array to load import values into.
Dim Imp_Arr() As Variant
'0 = location, 1= city, 2= st, 3=date site set, 4=pre-ins date, 5= mod name, 6= mod title, 7 = summary
ReDim Imp_Arr(Inspection_Total, 7)

'Walk through import sheet, for reach row, compare to the list of unique locations (to find where each row belongs)
For i = 2 To Import_Total
For x = 2 To Unique_Sheet.Cells(1, 2) + 1
If (Imp_Sheet.Cells(i, 3) = Unique_Sheet.Cells(x, 1)) Then
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)
'Comments on a specific location need to be on one row, this accomplishes that
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) = Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) & Imp_Sheet.Cells(i, 10) & " " & Imp_Sheet.Cells(i, 11) & " " & Imp_Sheet.Cells(i, 12) & ";" & Chr(10)
End If
Next x
Next i

'Output one row for each location.
For i = 0 To Inspection_Total

For Z = 0 To 7
'
Out_Sheet.Cells(i + 2, Z + 1).Value = Imp_Arr(i, Z)

Next Z

Next i

End Sub









share|improve this question















Background: End users wanted to automate the process of taking information out of our CRM software (in the form of a csv), and then process it into something more usable for their purposes. Ended up not getting used, but I did manage to make it run/work on old data.



The following code expects an import of values to be placed in a sheet labeled "Import", each row of the import is associated with a specific location that has been inspected, but there are multiple rows per location (different comments, and information for the location).



The code is meant to take these multiple rows, and create an output with only one row per location, while concatenating the information that isn't duplicated in the import rows.



Wanted to see how many pitfalls I've fallen into, I've taken college coursework with programming, but no real guidance in industry (learned a great deal through trial/error when asked to make something at work).



Code does run, but I'm particularly interested in knowing whether my use of an array is really bad practice or not. I use a similar structure for a lot of the VBA code I make that needs to deal with import data (I don't know of a better way to manipulate the data, leaving it in the sheets ends up being excessively slow on larger sets of data).



Sub ProcessData()

Dim Imp_Sheet As Worksheet
Set Imp_Sheet = Sheets("Import")
Dim Unique_Sheet As Worksheet
Set Unique_Sheet = Sheets("UniqueVals")
Dim Out_Sheet As Worksheet
Set Out_Sheet = Sheets("Output")

'Clear unique value sheet
Unique_Sheet.Cells.Clear

'Copy up to 3000 locations from the import sheet.
Imp_Sheet.Range("C1:C3000").Copy
Unique_Sheet.Paste (Unique_Sheet.Cells(1, 1))
'Remove duplicate locations
Unique_Sheet.Range("A1:A3000").RemoveDuplicates Columns:=(1), Header:=xlYes

'Find number of inspections(Could include duplicate inspections that I don't want)
Dim Inspection_Total As Long: Inspection_Total = Find_End(Unique_Sheet.Name)

For i = 2 To Inspection_Total
'Check if it's found the end of the unique value list
If (Unique_Sheet.Cells(i, 1).Value = "") Then
Exit For
End If
'give each unique value a number for future reference
Unique_Sheet.Cells(i, 2).Value = i - 1
Next i

Unique_Sheet.Cells(1, 2).Value = i - 2
'Change inspection total to be the actual number of inspections
Inspection_Total = i - 2

Dim Import_Total: Import_Total = Find_End(Imp_Sheet.Name)

'Prepare array to load import values into.
Dim Imp_Arr() As Variant
'0 = location, 1= city, 2= st, 3=date site set, 4=pre-ins date, 5= mod name, 6= mod title, 7 = summary
ReDim Imp_Arr(Inspection_Total, 7)

'Walk through import sheet, for reach row, compare to the list of unique locations (to find where each row belongs)
For i = 2 To Import_Total
For x = 2 To Unique_Sheet.Cells(1, 2) + 1
If (Imp_Sheet.Cells(i, 3) = Unique_Sheet.Cells(x, 1)) Then
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)
'Comments on a specific location need to be on one row, this accomplishes that
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) = Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 7) & Imp_Sheet.Cells(i, 10) & " " & Imp_Sheet.Cells(i, 11) & " " & Imp_Sheet.Cells(i, 12) & ";" & Chr(10)
End If
Next x
Next i

'Output one row for each location.
For i = 0 To Inspection_Total

For Z = 0 To 7
'
Out_Sheet.Cells(i + 2, Z + 1).Value = Imp_Arr(i, Z)

Next Z

Next i

End Sub






vba excel






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 5 '17 at 17:35









200_success

127k15148410




127k15148410










asked Oct 5 '17 at 15:20









Jack Of All Trades 234

1584




1584





bumped to the homepage by Community 4 hours ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







bumped to the homepage by Community 4 hours ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.














  • What is the reason for processing exactly 3000 rows in this Sub?
    – Doc Brown
    Oct 5 '17 at 17:50












  • @doc-brown I didn't know how many they would be attempting to run, but was fairly confident that 3000 would be an order of magnitude more than the likely scenario (using previous year's data for testing purposes was something like ~300 import lines).
    – Jack Of All Trades 234
    Oct 5 '17 at 18:13










  • I typically avoid such magic numbers in code. You can surely determine the used rows or cells in the input sheet, I guess. That will make your code more robust against future changes.
    – Doc Brown
    Oct 5 '17 at 18:54






  • 1




    It's best to use a Dictionary or some type of Collection when comparing unique values in two list. If you're not worried about clearing data not present in the imported data then you can simply write the whole array at one time to Sheets("UniqueVals"). Dynamic Ranges are preferred over static ones (e.g. Range("A1", Range("A" & Rows.Count).End(xlUp)) is better then Range("A1:A3000")).
    – user109261
    Oct 30 '17 at 5:54


















  • What is the reason for processing exactly 3000 rows in this Sub?
    – Doc Brown
    Oct 5 '17 at 17:50












  • @doc-brown I didn't know how many they would be attempting to run, but was fairly confident that 3000 would be an order of magnitude more than the likely scenario (using previous year's data for testing purposes was something like ~300 import lines).
    – Jack Of All Trades 234
    Oct 5 '17 at 18:13










  • I typically avoid such magic numbers in code. You can surely determine the used rows or cells in the input sheet, I guess. That will make your code more robust against future changes.
    – Doc Brown
    Oct 5 '17 at 18:54






  • 1




    It's best to use a Dictionary or some type of Collection when comparing unique values in two list. If you're not worried about clearing data not present in the imported data then you can simply write the whole array at one time to Sheets("UniqueVals"). Dynamic Ranges are preferred over static ones (e.g. Range("A1", Range("A" & Rows.Count).End(xlUp)) is better then Range("A1:A3000")).
    – user109261
    Oct 30 '17 at 5:54
















What is the reason for processing exactly 3000 rows in this Sub?
– Doc Brown
Oct 5 '17 at 17:50






What is the reason for processing exactly 3000 rows in this Sub?
– Doc Brown
Oct 5 '17 at 17:50














@doc-brown I didn't know how many they would be attempting to run, but was fairly confident that 3000 would be an order of magnitude more than the likely scenario (using previous year's data for testing purposes was something like ~300 import lines).
– Jack Of All Trades 234
Oct 5 '17 at 18:13




@doc-brown I didn't know how many they would be attempting to run, but was fairly confident that 3000 would be an order of magnitude more than the likely scenario (using previous year's data for testing purposes was something like ~300 import lines).
– Jack Of All Trades 234
Oct 5 '17 at 18:13












I typically avoid such magic numbers in code. You can surely determine the used rows or cells in the input sheet, I guess. That will make your code more robust against future changes.
– Doc Brown
Oct 5 '17 at 18:54




I typically avoid such magic numbers in code. You can surely determine the used rows or cells in the input sheet, I guess. That will make your code more robust against future changes.
– Doc Brown
Oct 5 '17 at 18:54




1




1




It's best to use a Dictionary or some type of Collection when comparing unique values in two list. If you're not worried about clearing data not present in the imported data then you can simply write the whole array at one time to Sheets("UniqueVals"). Dynamic Ranges are preferred over static ones (e.g. Range("A1", Range("A" & Rows.Count).End(xlUp)) is better then Range("A1:A3000")).
– user109261
Oct 30 '17 at 5:54




It's best to use a Dictionary or some type of Collection when comparing unique values in two list. If you're not worried about clearing data not present in the imported data then you can simply write the whole array at one time to Sheets("UniqueVals"). Dynamic Ranges are preferred over static ones (e.g. Range("A1", Range("A" & Rows.Count).End(xlUp)) is better then Range("A1:A3000")).
– user109261
Oct 30 '17 at 5:54










1 Answer
1






active

oldest

votes

















up vote
0
down vote













Variables



You did a good job of naming your variables as what they are, but you didn't declare some.



Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know.



When you don't define your variable, VBA will declare it as a Variant type that can hold any type of data. While this may be more flexible, it adds processing time to your macro as VBA decides or tests for the type. Additionally, since a Variant can be any type of data, you may miss out on valuable troubleshooting information on Type Mismatch



Also, you can do better with the worksheets. Worksheets have a CodeName property - View Properties window (F4) and the (Name) field (the one at the top) can be used as the worksheet name. This way you can avoid Sheets("Import") and instead just use Import.



You also ran into the pitfall of VBA naming style. Standard VBA naming conventions have camelCase for local variables and PascalCase for other variables and names.





You are missing a function Find_End which I assume just find the last row. So it would be something like this



Dim inspectionLastRow As Long
inspectionLastRow = UniqueSheet.Cells(Rows.Count, 1).End(xlUp).Row


Now you have your loops. You have an i loop, a x loop and a Z loop. In this case I would give them more specific names -



For inspectionIndex = 2 To inspectionLastRow
For importIndex = 2 To importLastRow
for uniqueIndex = 2 to uniqueLastRow
For targetColumn = 0 To 7


But with the last one, you are using it as a column so you'd be better off adjusting the array than the column -



 For z = 1 To 8
Out_Sheet.Cells(i + 2, z).Value = Imp_Arr(i, z - 1)


When you have a string like this -




Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"



I find it better to get that out of the way up top



Const INPUT_REQUIRED As String = "MANUAL IMPORT REQUIRED"




You have a lot of comments. Comments - "code tell you how, comments tell you why". The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.



Writing to sheet



You have this chunk of code




Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)



That is pretty difficult to follow, yeah? Rearrange your array and write it all at once -



 Imp_Sheet.Range(.Cells(i, 3), .Cells(i, 8)) = Imp_Arr


Or pull out dimensions of the array into new arrays to put them on the sheet.





This If block doesn't need to be a block




If (Unique_Sheet.Cells(i, 1).Value = "") Then
Exit For
End If



 If IsEmpty(Unique_Sheet.Cells(i, 1)) Then Exit For





share|improve this answer





















    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f177226%2fvba-code-meant-for-a-many-to-one-translation-of-import-rows%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Variables



    You did a good job of naming your variables as what they are, but you didn't declare some.



    Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know.



    When you don't define your variable, VBA will declare it as a Variant type that can hold any type of data. While this may be more flexible, it adds processing time to your macro as VBA decides or tests for the type. Additionally, since a Variant can be any type of data, you may miss out on valuable troubleshooting information on Type Mismatch



    Also, you can do better with the worksheets. Worksheets have a CodeName property - View Properties window (F4) and the (Name) field (the one at the top) can be used as the worksheet name. This way you can avoid Sheets("Import") and instead just use Import.



    You also ran into the pitfall of VBA naming style. Standard VBA naming conventions have camelCase for local variables and PascalCase for other variables and names.





    You are missing a function Find_End which I assume just find the last row. So it would be something like this



    Dim inspectionLastRow As Long
    inspectionLastRow = UniqueSheet.Cells(Rows.Count, 1).End(xlUp).Row


    Now you have your loops. You have an i loop, a x loop and a Z loop. In this case I would give them more specific names -



    For inspectionIndex = 2 To inspectionLastRow
    For importIndex = 2 To importLastRow
    for uniqueIndex = 2 to uniqueLastRow
    For targetColumn = 0 To 7


    But with the last one, you are using it as a column so you'd be better off adjusting the array than the column -



     For z = 1 To 8
    Out_Sheet.Cells(i + 2, z).Value = Imp_Arr(i, z - 1)


    When you have a string like this -




    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"



    I find it better to get that out of the way up top



    Const INPUT_REQUIRED As String = "MANUAL IMPORT REQUIRED"




    You have a lot of comments. Comments - "code tell you how, comments tell you why". The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.



    Writing to sheet



    You have this chunk of code




    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
    Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)



    That is pretty difficult to follow, yeah? Rearrange your array and write it all at once -



     Imp_Sheet.Range(.Cells(i, 3), .Cells(i, 8)) = Imp_Arr


    Or pull out dimensions of the array into new arrays to put them on the sheet.





    This If block doesn't need to be a block




    If (Unique_Sheet.Cells(i, 1).Value = "") Then
    Exit For
    End If



     If IsEmpty(Unique_Sheet.Cells(i, 1)) Then Exit For





    share|improve this answer

























      up vote
      0
      down vote













      Variables



      You did a good job of naming your variables as what they are, but you didn't declare some.



      Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know.



      When you don't define your variable, VBA will declare it as a Variant type that can hold any type of data. While this may be more flexible, it adds processing time to your macro as VBA decides or tests for the type. Additionally, since a Variant can be any type of data, you may miss out on valuable troubleshooting information on Type Mismatch



      Also, you can do better with the worksheets. Worksheets have a CodeName property - View Properties window (F4) and the (Name) field (the one at the top) can be used as the worksheet name. This way you can avoid Sheets("Import") and instead just use Import.



      You also ran into the pitfall of VBA naming style. Standard VBA naming conventions have camelCase for local variables and PascalCase for other variables and names.





      You are missing a function Find_End which I assume just find the last row. So it would be something like this



      Dim inspectionLastRow As Long
      inspectionLastRow = UniqueSheet.Cells(Rows.Count, 1).End(xlUp).Row


      Now you have your loops. You have an i loop, a x loop and a Z loop. In this case I would give them more specific names -



      For inspectionIndex = 2 To inspectionLastRow
      For importIndex = 2 To importLastRow
      for uniqueIndex = 2 to uniqueLastRow
      For targetColumn = 0 To 7


      But with the last one, you are using it as a column so you'd be better off adjusting the array than the column -



       For z = 1 To 8
      Out_Sheet.Cells(i + 2, z).Value = Imp_Arr(i, z - 1)


      When you have a string like this -




      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"



      I find it better to get that out of the way up top



      Const INPUT_REQUIRED As String = "MANUAL IMPORT REQUIRED"




      You have a lot of comments. Comments - "code tell you how, comments tell you why". The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.



      Writing to sheet



      You have this chunk of code




      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
      Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)



      That is pretty difficult to follow, yeah? Rearrange your array and write it all at once -



       Imp_Sheet.Range(.Cells(i, 3), .Cells(i, 8)) = Imp_Arr


      Or pull out dimensions of the array into new arrays to put them on the sheet.





      This If block doesn't need to be a block




      If (Unique_Sheet.Cells(i, 1).Value = "") Then
      Exit For
      End If



       If IsEmpty(Unique_Sheet.Cells(i, 1)) Then Exit For





      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        Variables



        You did a good job of naming your variables as what they are, but you didn't declare some.



        Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know.



        When you don't define your variable, VBA will declare it as a Variant type that can hold any type of data. While this may be more flexible, it adds processing time to your macro as VBA decides or tests for the type. Additionally, since a Variant can be any type of data, you may miss out on valuable troubleshooting information on Type Mismatch



        Also, you can do better with the worksheets. Worksheets have a CodeName property - View Properties window (F4) and the (Name) field (the one at the top) can be used as the worksheet name. This way you can avoid Sheets("Import") and instead just use Import.



        You also ran into the pitfall of VBA naming style. Standard VBA naming conventions have camelCase for local variables and PascalCase for other variables and names.





        You are missing a function Find_End which I assume just find the last row. So it would be something like this



        Dim inspectionLastRow As Long
        inspectionLastRow = UniqueSheet.Cells(Rows.Count, 1).End(xlUp).Row


        Now you have your loops. You have an i loop, a x loop and a Z loop. In this case I would give them more specific names -



        For inspectionIndex = 2 To inspectionLastRow
        For importIndex = 2 To importLastRow
        for uniqueIndex = 2 to uniqueLastRow
        For targetColumn = 0 To 7


        But with the last one, you are using it as a column so you'd be better off adjusting the array than the column -



         For z = 1 To 8
        Out_Sheet.Cells(i + 2, z).Value = Imp_Arr(i, z - 1)


        When you have a string like this -




        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"



        I find it better to get that out of the way up top



        Const INPUT_REQUIRED As String = "MANUAL IMPORT REQUIRED"




        You have a lot of comments. Comments - "code tell you how, comments tell you why". The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.



        Writing to sheet



        You have this chunk of code




        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)



        That is pretty difficult to follow, yeah? Rearrange your array and write it all at once -



         Imp_Sheet.Range(.Cells(i, 3), .Cells(i, 8)) = Imp_Arr


        Or pull out dimensions of the array into new arrays to put them on the sheet.





        This If block doesn't need to be a block




        If (Unique_Sheet.Cells(i, 1).Value = "") Then
        Exit For
        End If



         If IsEmpty(Unique_Sheet.Cells(i, 1)) Then Exit For





        share|improve this answer












        Variables



        You did a good job of naming your variables as what they are, but you didn't declare some.



        Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know.



        When you don't define your variable, VBA will declare it as a Variant type that can hold any type of data. While this may be more flexible, it adds processing time to your macro as VBA decides or tests for the type. Additionally, since a Variant can be any type of data, you may miss out on valuable troubleshooting information on Type Mismatch



        Also, you can do better with the worksheets. Worksheets have a CodeName property - View Properties window (F4) and the (Name) field (the one at the top) can be used as the worksheet name. This way you can avoid Sheets("Import") and instead just use Import.



        You also ran into the pitfall of VBA naming style. Standard VBA naming conventions have camelCase for local variables and PascalCase for other variables and names.





        You are missing a function Find_End which I assume just find the last row. So it would be something like this



        Dim inspectionLastRow As Long
        inspectionLastRow = UniqueSheet.Cells(Rows.Count, 1).End(xlUp).Row


        Now you have your loops. You have an i loop, a x loop and a Z loop. In this case I would give them more specific names -



        For inspectionIndex = 2 To inspectionLastRow
        For importIndex = 2 To importLastRow
        for uniqueIndex = 2 to uniqueLastRow
        For targetColumn = 0 To 7


        But with the last one, you are using it as a column so you'd be better off adjusting the array than the column -



         For z = 1 To 8
        Out_Sheet.Cells(i + 2, z).Value = Imp_Arr(i, z - 1)


        When you have a string like this -




        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"



        I find it better to get that out of the way up top



        Const INPUT_REQUIRED As String = "MANUAL IMPORT REQUIRED"




        You have a lot of comments. Comments - "code tell you how, comments tell you why". The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.



        Writing to sheet



        You have this chunk of code




        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 0) = Imp_Sheet.Cells(i, 3)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 1) = Imp_Sheet.Cells(i, 7)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 2) = Imp_Sheet.Cells(i, 8)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 3) = "MANUAL INPUT REQUIRED"
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 4) = Imp_Sheet.Cells(i, 6)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 5) = Imp_Sheet.Cells(i, 4)
        Imp_Arr(Unique_Sheet.Cells(x, 2) - 1, 6) = Imp_Sheet.Cells(i, 5)



        That is pretty difficult to follow, yeah? Rearrange your array and write it all at once -



         Imp_Sheet.Range(.Cells(i, 3), .Cells(i, 8)) = Imp_Arr


        Or pull out dimensions of the array into new arrays to put them on the sheet.





        This If block doesn't need to be a block




        If (Unique_Sheet.Cells(i, 1).Value = "") Then
        Exit For
        End If



         If IsEmpty(Unique_Sheet.Cells(i, 1)) Then Exit For






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 18 at 23:27









        Raystafarian

        5,7841047




        5,7841047






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f177226%2fvba-code-meant-for-a-many-to-one-translation-of-import-rows%23new-answer', 'question_page');
            }
            );

            Post as a guest




















































































            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre