How to append data to a column in a loop - excel

My script takes data from multiple sheets and creates a new spreadsheet. The problem I am running into is how to append to the end of a column. I tried this:
LastRow = Sheets("Test").Cells(Rows.Count, "A").End(xlUp).Row
Where LastRow is defined as a long but I ran into an error when my loop continued going around. Here is what I have so far:
Sub autoFill()
Dim wb As Workbook, ws As Worksheet
Dim LastRow As Long
Dim Unit As String
Dim ddg As Variant, i As Variant
Set wb = ActiveWorkbook
Set ws = wb.Worksheets("Mapping")
ddg = ws.Range("F4:F21").Value
For Each i In ddg
Unit = "Unit #" & i
LastRow = Sheets("Test").Cells(Rows.Count, "A").End(xlUp).Row
Sheets(Unit).Range("A2:A100").Copy Destination:=Sheets("Test").Range("A1" & LastRow)
Sheets(Unit).Range("B2:B100").Copy Destination:=Sheets("Test").Range("B1" & LastRow)
Next i
End Sub

Just pick a range WAY above whatever the last row might be in whatever column will be populated (A in this case) when using xlUp. Add 1 to get to the next row:
LastRow = Sheets("Test").Range("A50000").End(xlUp).Row + 1
LAstRow now has a number that is equal to the first unused row in Column A of sheet Test.
Now concatenate that number to "A" to make a range like "A50". Right now you are doing:
Sheets(Unit).Range("A2:A100").Copy Destination:=Sheets("Test").Range("A1" & LastRow)
Which is concatenating the number to "A1" so you get "A150" which is nonsense... Instead:
Sheets(Unit).Range("A2:A100").Copy Destination:=Sheets("Test").Range("A" & LastRow)

Related

How do I set a range of cell values to another range of cells in a different worksheet in VBA?

I have quite a few rows of inputs in the first worksheet. I am attempting to create a macro that loops through all of the rows by setting the values in a second worksheet equal to that of each row in the first. The second row runs the calculation and returns the outputs to the first worksheet. Nothing seems to happen when I run this. Any ideas?
Dim lRow As Integer
Dim rowStart As Integer
Dim i As Integer
rowStart = 7
lRow = Range("B1048576").End(xlUp).Row
For i = rowStart To lRow
Worksheets("CalcSheet").Range("C" & 5 & ":" & "Y" & 5) = Worksheets("DesignSheet").Range("C" & i & ":" & "Y" & i)
Worksheets("DesignSheet").Range("Z" & i & ":" & "AA" & i) = Worksheets("CalcSheet").Range("Z5:AA5")
Worksheets("DesignSheet").Range("AD" & i & ":" & "AE" & i) = Worksheets("CalcSheet").Range("AD5:AE5")
next i
Something like this is a bit more explicit in terms of what sheets are being referred to. Other comments in-line.
Sub Test()
Const ROW_START As Long = 7 'use Const for fixed values
Dim lRow As Long, i As Long 'use long instead of integer
Dim wsCalc As Worksheet, wsDes As Worksheet
'use worksheet variables and an explicit workbook object
Set wsCalc = ThisWorkbook.Worksheets("CalcSheet")
Set wsDes = ThisWorkbook.Worksheets("DesignSheet")
For i = ROW_START To wsDes.Cells(Rows.Count, "B").End(xlUp).row
With wsDes.Rows(i)
wsCalc.Range("C5:Y5").Value = .Range("C1:Y1").Value 'here C1:Y1 is *relative* to row i
wsCalc.Calculate 'to be sure...
.Range("Z1:AA1").Value = wsCalc.Range("Z5:AA5").Value
.Range("AD1:AE1").Value = wsCalc.Range("AD5:AE5").Value
End With
Next i
End Sub
A bit more about Range as used above...
Range() and Cells() are relative to the object they're called on, so
myWorksheet.Range("A1").Address '>> A1
myWorksheet.Range("B2:C3").Range("A1").Address '>> B2
So we're using wsCalc.Range() (fixed ranges) but moving the wsDes ranges by calling Range on wsDes.Rows(i)

In VBA code,how to add values to a listbox using for each cell approach with defining a range End(XlDown)?

I have created a macro file with Forms and Word to Excel.
In this coding fewthings are not working as per my expectation.
Get unique Employee Name from Excel data base.
I want to add unique employee names from excel database and get is saved in a sheet. After that those values to be added to list box. Here i cannot define a range like "A1:A10".. I want to choose the data from A1 to end data.
If for each cell approach will not work, please help in do while approach
I need help in defining the range and code given below
ListEmployeeName.Clear
For Each cell In Worksheets("SunEmployeeDetails").Range("A1").End(xlDown)
ListEmployeeName.AddItem (cell.Value)
Next
ListEmployeeName.Value = Worksheets("SunEmployeeDetails").Range("A1")
End Sub
Find Last Row and then define your range Range("A1:A" & LastRow)
You can also find the last row and loop through the range using a For loop. Also to get unique Employee Name, you can use On Error Resume Next with a Collection as shown below. I have commented the code below so you should not have a problem understanding it. But if you do then simply ask.
Is this what you are trying? (Untested).
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Dim col As New Collection
Dim itm As Variant
Set ws = Worksheets("SunEmployeeDetails")
With ws
'~~> Find Last row
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Loop through the range and add it to the unique
'~~> collection using "On Error Resume Next"
For i = 1 To lRow
On Error Resume Next
col.Add .Range("A" & i).Value, CStr(.Range("A" & i).Value)
On Error GoTo 0
Next i
End With
ListEmployeeName.Clear
'~~> add the itme from collection to the listbox
For Each itm In col
ListEmployeeName.AddItem itm
Next itm
End Sub
Here is my take on it, techniques taken from here:
Methode 1: Using a dictionary
Dim lr As Long, x As Long
Dim arr As Variant
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
With Sheet1 'Change accordingly
'Find the last used row
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
arr = .Range("A1:A" & lr).Value
End With
'Loop through memory and fill dictionary
For x = LBound(arr) To UBound(arr)
dict(arr(x, 1)) = 1
Next x
'Add array to Listbox
Me.ListEmployeeName.List = dict.Keys
Methode 2: Using Evaluation
Dim lr As Long
Dim arr As Variant
With Sheet1 'Change accordingly
'Find the last used row
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
'Get array of unique values
arr = Filter(.Evaluate("TRANSPOSE(If(Row(A1:A" & lr & ")<>MATCH(A1:A" & lr & ",A1:A" & lr & ",0),""|"",A1:A" & lr & "))"), "|", False)
'Add array to Listbox
Me.ListEmployeeName.List = arr
End With

Find the total of the same column from multiple sheets and express totals next to sheet name on new sheet

I'm looking to create a macro that will display the Sum from a set column of each of multiple sheets. I need the total of column "K" to be shown 1 row from the last entry of a variable number of entries. It is a requirment that this is in VBA as it needs to run with a number of other functions.
I've tried the below code but it does not give the expected result and seems to be drawing data from other sheets.
Sub SumWorksheets()
Dim LastRow As Long
Dim ws As Worksheet
For Each ws In Worksheets
LastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ws.Range("K" & LastRow + 1) = Application.WorksheetFunction.Sum(Range("K2:K" & ws.Rows.Count))
Next
End Sub
I want the Total of all numbers in Column "K" to display 2 rows below the last number in Row "K"
Declared and fully use ws and LastRow variables. Not using can cause code to pull values from another worksheet. Per comment from #LoveCoding, using a different column as the LastRow can overwrite a cell in Col K. You should have used the LastRow variable, in the Sum function.
Dim ws As Worksheet, LastRow As Long
For Each ws In ThisWorkbook.Worksheets
LastRow = ws.Range("K" & ws.Rows.Count).End(xlUp).Row
ws.Range("K" & LastRow + 1) = Application.WorksheetFunction.Sum(ws.Range("K2:K" & LastRow))
Next

Excel VBA offset function

I have an Excel file with information in column A and column B. Since these columns could vary in the number of rows I would like to use the function offset so that I could print the formula in one time as an array rather than looping over the formula per cell (the dataset contains almost 1 million datapoints).
My code is actually working the way I want it to be I only can't figure out how to print the code in Range(D1:D5). The outcome is now printed in Range(D1:H1). Anybody familiar how to use this offset within a for statement?
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set example = Range("A1:A1")
For i = 1 To LastRow
example.Offset(0, i + 2).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
End Sub
Using the Offset(Row, Column), you want to offset with the increment of row (i -1), and 3 columns to the right (from column "A" to column "D")
Try the modified code below:
Set example = Range("A1")
For i = 1 To LastRow
example.Offset(i - 1, 3).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
One way of outputting the formula in one step, without looping, to the entire range, is to use the R1C1 notation:
Edit: Code modified to properly qualify worksheet references
Option Explicit
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
With sht
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set example = .Range(.Cells(1, 1), .Cells(LastRow, 1))
End With
example.Offset(columnoffset:=3).FormulaR1C1 = "=sum(rc[-3],rc[-2])"
End Sub
You don't need to use VBA for this. Simply type =sum(A1:B1) in cell D1 and then fill it down.
If you're going to use VBA anyway, use this:
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set example = Range("A1:A1")
For i = 1 To LastRow
example.Offset(i - 1, 3).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
End Sub
The way offset works is with row offset, column offset. You want the column to always be fixed at 3 to the right.

Vba comparing then copying two different Sheets

I realize there are a few different similar ideas on here. But I need help with this simple compare function.
My goal is to compare two different cells and if they are the same, replace it with its full non-abbreviated name.
Thank you for your time!!!
I.E
Sheet1 Sheet2
Column H Column A Column B
Dept Dept Department
This is what I have (Yes simple), but the cell H is not updating to the non-abbreviation:
Sub updateDeptNames()
'Format user ID from the email column
Dim ws As Worksheet, ws2 As Worksheet
Dim LastRow As Long, i As Long
Dim tmpArray() As String, tempDept As String
Set ws = ActiveWorkbook.Sheets("Student_Travel_DB") '--> This is the relevant sheet
Set ws2 = ActiveWorkbook.Sheets("gokoutd") '--> This is the relevant sheet
LastRow = 1000 ''Bug finding the last row, had to hard code it
For i = 2 To LastRow 'Iterate through all the rows in the sheet
For j = 2 To 112
tempDept = ws2.Range("A" & j).Value
If ws.Range("H" & i).Value = tempDept Then
ws.Range("H" & i) = ws2.Range("B" & j).Value
End If
Next j
Next i
End Sub
You can more easily use VLOOKUP either on your worksheet or with VBA:
Sub GetFullName()
Dim cl As Range, data As Range, lookUpRng As Range
Set data = Worksheets("Student_Travel_DB").Range("A1:A10")
Set lookUpRng = Worksheets("gokoutd").Range("A1:B10")
On Error Resume Next
For Each cl In data
cl = WorksheetFunction.VLookup(cl, lookUpRng, 2, False)
Next cl
End Sub
You'll need to change your range references.

Resources