Assigning values to array vba - vba

I don't have experience using arrays in VBA and I got lost. What I try to do is the following:
In the column A I have ~15 strings (number is not fixed sometimes it is more sometimes less)
I remove duplicates and then for each name in the column A I would like to create separate sheet in the file.
I created an array to which I tried to assign each name from A with this loop:
Sub assigningvalues()
Dim i As Integer
Dim myArray(20) As Variant
Dim finalrow As Long
ActiveSheet.Range("A1", Range("A1").End(xlDown)).RemoveDuplicates Columns:=Array(1)
finalrow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlDown).Row
'For i = 2 To finalrow -> I get overflow error when I use this range
For i = 2 To Cells(20, 1)
myArray(i) = Cells(i, 1).Value
Next i
'I check with the lines below if values were assigned
Cells(2, 4).Value = myArray(4)
Cells(3, 4).Value = myArray(2)
End Sub
Nevertheless values from the cells to do not assign to the array
Moreover when I try to use finalrow as range for the loop I get overflow error (It is not a big problem as there are workarounds, although it would be nice to know what I've done wrong)

Try the code below:
Option Explicit
Sub assigningvalues()
Dim i As Long
Dim myArray(20) As Variant
Dim FinalRow As Long
Dim Sht As Worksheet
Set Sht = ThisWorkbook.Sheets("Sheet1") ' modify "Sheet1" to your sheet's name
With Sht
.Range("A1", .Range("A1").End(xlDown)).RemoveDuplicates Columns:=Array(1)
FinalRow = .Cells(.Rows.Count, "A").End(xlUp).Row ' get last row in column "A"
For i = 2 To FinalRow
myArray(i) = Cells(i, 1).Value
Next i
'I check with the lines below if values were assigned
.Cells(2, 4).Value = myArray(4)
.Cells(3, 4).Value = myArray(2)
End With
End Sub
Note: you can read the contents of the Range to a 1-D Array without a For loop, using Application.Transpose, you need to change the line you define it to:
Dim myArray As Variant
and populate the entire array using:
myArray = Application.Transpose(.Range("A2:A" & FinalRow))

Try the code below:
Sub assigningvalues()
Dim myArray As Variant
ActiveSheet.Range("A1", Range("A1").End(xlDown)).RemoveDuplicates Columns:=Array(1)
myArray = ActiveSheet.Range("A1", Range("A1").End(xlDown))
For Each element In myArray
ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)).Name = element
Next element
End Sub
NOTES: The problem with your above code was, that
ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlDown).Row
returned the absolut number of rows in the sheet, not the used ones. Since your array has length 20 and the sheet about 1 Mio. rows, you have an overflow. you can check this by using
Debug.Print ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlDown).Row
In the above code, after you remove dublicates, you again go down from A1 to the end and save the range to an array. The array myArray now contains all the cell values in your reduced range.
Now you loop over the elements with
For Each element in myArray
and create a new sheet with Workbook.Sheets.Add and assign the name my setting Sheets(index).name = element
The above code should work for you. Few remarks:
Instead of using "ActiveSheet", ThisWorkbook, etc. You should always start a Sub with this:
Dim wb As Workbook
Set wb = ThisWorkbook 'for the workbook containing the code
Set wb = Workbooks(workbookName) 'to reference an other Workbook
'And for all the sheets you are using
Dim ws As Worksheet
Set ws = wb.Sheets(sheetName) 'this way you avoid problems with multiple
workbooks that are open and active or
unactive sheets.

Related

VBA Excel Populate ListBox with multiple columns

This may be a cheap question for some but I'm totally confused on how to populate my listbox.
Using this line I can populate the listbox as shown below:
ListBox1.List = Sheets("Sheet1").Cells(1, 1).CurrentRegion.Value
or
Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Set ws = Worksheets("Sheet1")
For i = 1 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row Step 1
If ws.Cells(i, 1).Value <> vbNullString Then Me.ListBox1.AddItem
ws.Cells(i, 1).Value
Next i
Below is the data I'm planning to use to populate the list box and is progressive. Only the column has the fix count.
Someone please enlighten me on how to populate a list box adapative to multiple columns and rows using FOR LOOP as shown in my code above. Any help appreciated. Thanks.
Methods
It's always better to loop through an array than a range - it's much faster.
It's even faster to create a variant data field array with a one liner instead of redimensioning a predeclared array and fill it in an extra loop as proposed by Siddharth Rout (though a good method :-) Note: The code below is based on his Approach referenced in the above comment just to demonstrate the difference.
Fill ListBox1.List with the array (same method, but reverse direction).
Code
Private Sub CommandButton1_Click()
' Purpose: fill listbox with range values after clicking on CommandButton1
' (code could be applied to UserForm_Initialize(), too)
' Note: based on #Siddharth-Rout 's proposal at https://stackoverflow.com/questions/10763310/how-to-populate-data-from-a-range-multiple-rows-and-columns-to-listbox-with-vb
' but creating a variant data field array directly from range in a one liner
' (instead of filling a redimensioned array with range values in a loop)
Dim ws As Worksheet
Dim rng As Range
Dim MyArray ' variant, receives one based 2-dim data field array
'~~> Change your sheetname here
Set ws = Sheets("Sheet1")
'~~> Set you relevant range here
Set rng = ws.Range("A1:C" & ws.Range("A" & ws.Rows.Count).End(xlUp).Row)
With Me.ListBox1
.Clear
.ColumnHeads = False
.ColumnCount = rng.Columns.Count
'~~> create a one based 2-dim datafield array
MyArray = rng
'~~> fill listbox with array values
.List = MyArray
'~~> Set the widths of the column here. Ex: For 5 Columns
'~~> Change as Applicable
.ColumnWidths = "50;50;50"
.TopIndex = 0
End With
End Sub
Additional hints
Another advantage of the array method - it overcomes the built-in limitation of only 10 columns when using the .AddItem method.
Furthermore, keep in mind that listbox indexing is zero based, so for example you get the e-mail address (column 3, index 2) of your first item row (index 0) via ListBox1.List(0, 2), whereas the data field array becomes automatically a one based 2-dim array.
You aren't restricted to use the .List method to get Information out of the listbox, you can reverse the row - column order by using ListBox1.Column" or even create a new array out of it, which remains a 2-dim object, even if there is only ONE item (note: theApplication.Transpose` method would redim a 2 dimensional array with only one row to a 1-dim array).
A last point: you can easily dump back again the whole listbox to an Excel sheet via rng = ListBox1.List, but take care to define the correct range.
How about this:
Sub foo()
Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Set ws = Worksheets("Sheet1")
ListBox1.Clear
ListBox1.columnCount = 3
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For i = 1 To LastRow
If ws.Cells(i, 1).Value <> vbNullString Then ListBox1.AddItem ws.Cells(i, 1).Value
If ws.Cells(i, 2).Value <> vbNullString Then ListBox1.List(i - 1, 1) = ws.Cells(i, 2).Value
If ws.Cells(i, 3).Value <> vbNullString Then ListBox1.List(i - 1, 2) = ws.Cells(i, 3).Value
Next i
End Sub

Can't get my Ranges set up from my spreadsheet using VBA

My overall goal here is to grab the values and row indices of three different columns on the original spreadsheet, evaluate them, and then save them to a new spreadsheet. I am wanted to accomplish this by using a macro initiated by a button on the original spreadsheet.
The plan to accomplish this was to
create a Range for each column
Loop through the most significant Range to grab and evaluate the each cell value
perform nested loops within the first loop to further evaluate the other two Ranges and grab their values
assign values to variables
create the new spreadsheet from a template
write the values to the respective columns
save the new spreadsheet
When I run the code below I get the error listed below. I'm confused because I thought this is how you reference an entire column:
Sub Transfer2NewWorkbook()
Dim currentsheet As String
Dim newsheet As String
Dim analysisDate As String
Dim initial As String
Dim aInitial() As String
Dim analystInit As String
Dim batchNo As String
Dim wb As Object
Dim dataRangeA As Range, dataRangeB As Range, dataRangeI As Range
Set dataA = CreateObject("Scripting.Dictionary")
' Grab and Create filenames
currentsheet = ActiveWorkbook.Name
newsheet = currentsheet & "-" & "uploadable"
' Grab data from original spreadsheet
analysisDate = ActiveWorkbook.Sheets(1).Cells(1, 9).Value
initial = ActiveWorkbook.Sheets(1).Cells(1, 2).Value
aInitial = Split(initial, "/")
analystInit = aInitial(1)
Set dataRangeA = Range("A4:A").Select ' <-- Line causing error
Set dataRangeB = Range("B4:B").Select
Set dataRangeI = Range("I4:I").Select
For i = 1 To dataRangeA.Rows.Count
dataA.Add Key:=i, Item:=dataRangeA.Cells.Value
Next i
Set wb = Workbooks.Add("C:\Users\dalythe\documents\uploadtemp.xlsx")
ActiveWorkbook.Sheets(1).Cells(3, 2).Value = analysisDate
ActiveWorkbook.Sheets(1).Cells(3, 4).Value = analystInit
ActiveWorkbook.SaveAs (newsheet & ".xlsx")
End Sub
try this:
Set dataRangeA = Range("A:A").Select
Set dataRangeB = Range("B:B").Select
Set dataRangeI = Range("I:I").Select
For i = 4 To dataRangeA.Rows.Count
dataA.Add Key:=i, Item:=dataRangeA.Cells.Value
Next i
After removing the .Select, my ranges were accepted.
Set dataRangeA = Range("A:A")
Set dataRangeB = Range("B:B")
Set dataRangeI = Range("I:I")
For i = 4 To dataRangeA.Rows.Count
dataA.Add Key:=i, Item:=dataRangeA.Cells.Value
Next i
Thanks for the input YowE3k. Now I have to think on how I want my loop to end. Because doing it the way I have it above will cause it to run out of memory. The spreadsheet will not have a "predefined" number of rows. I guess I will have to have the user type "End" in the cell of the last row or something.
Your problems with the particular line throwing the error are caused by two things:
"A4:A" is not a valid address in Excel. You can either use "A:A" for the entire column or define the end of the range, e.g. "A4:A272".
The Range.Select method does not return an object, so Set dataRangeA = Range("A4:A").Select is effectively Set dataRangeA =.
To fix your specific error, you could do something like:
Set dataRangeA = Range("A4", Cells(Rows.Count, "A").End(xlUp))
However, using unqualified Cells and Range and Rows is a dangerous habit to get into once you have more than one worksheet / workbook being used in your code, because those objects default to referring to the ActiveSheet in the ActiveWorkbook and that may not be the one you are expecting it to be.
The code below ensures that each object is qualified, plus makes some other improvements to your code (such as the inevitable out-of-memory error that would arise in populating the Dictionary).
Sub Transfer2NewWorkbook()
Dim currentsheet As String
Dim newsheet As String
Dim analysisDate As String
Dim initial As String
Dim aInitial() As String
Dim analystInit As String
Dim batchNo As String
Dim wb As Object
Dim dataRangeA As Range, dataRangeB As Range, dataRangeI As Range
Dim dataA As Object ' declare this, unless you have declared it at a higher
' level scope
Set dataA = CreateObject("Scripting.Dictionary")
' Grab and Create filenames
currentsheet = ActiveWorkbook.Name
newsheet = currentsheet & "-" & "uploadable"
'Use a With block to avoid having to constantly refer
' to "ActiveWorkbook.Sheets(1)"
With ActiveWorkbook.Sheets(1)
' Grab data from original spreadsheet
analysisDate = .Cells(1, 9).Value
initial = .Cells(1, 2).Value
aInitial = Split(initial, "/")
analystInit = aInitial(1)
Set dataRangeA = .Range("A4", .Cells(.Rows.Count, "A").End(xlUp))
Set dataRangeB = .Range("B4", .Cells(.Rows.Count, "B").End(xlUp))
Set dataRangeI = .Range("I4", .Cells(.Rows.Count, "I").End(xlUp))
'This loop is making every entry in the Dictionary contain the value of
'every cell in the range - i.e. each of the 1048573 entries in the Dictionary
'would have contained an array which was dimensioned As (1 To 1048573, 1 To 1)
'For i = 1 To dataRangeA.Rows.Count
' dataA.Add Key:=i, Item:=dataRangeA.Cells.Value
'Next i
Dim cel As Range
For Each cel in dataRangeA
dataA.Add Key:=cel.Row, Item:=cel.Value
'or
'dataA.Add Key:=cel.Row - 3, Item:=cel.Value
'if you wanted A4's value to have a key of 1
Next
'Note: If you just wanted an array of values, you could have used
' Dim dataA As Variant
' dataA = Application.Transpose(.Range("A4", .Cells(.Rows.Count, "A").End(xlUp)))
'and then access each value using dataA(1) for the value from A4,
'dataA(2) for the value from A5, etc.
'This then gets rid of the need for dataRangeA, and the need for a
' dictionary object, and the need for the loop populating the dictionary.
End With
Set wb = Workbooks.Add("C:\Users\dalythe\documents\uploadtemp.xlsx")
With wb.Worksheets(1)
.Cells(3, 2).Value = analysisDate
.Cells(3, 4).Value = analystInit
End With
wb.SaveAs newsheet & ".xlsx"
End Sub

Cosolidating large excel files, cant go around buffer overflow

I am trying to consolidate multiple large excel files into one single file using the following code
Sub Macro1()
Application.DisplayAlerts = False
Dim Country As String
Dim i As Integer
Dim j As Integer
Dim k As Integer
k = 2
For i = 1 To 50
Windows("Try2").Activate
Country = Worksheets("Names").Cells(i, 1).Value
Workbooks.Open Filename:= "C:path\" & Country & " "
ActiveWorkbook.Sheets("Main").Activate
finalrow = Cells(Rows.Count, 1).End(xlUp).Row
Workbooks(Country).Sheets("Main").Range(Cells(1, 1), Cells(10000, 64)).Copy
Workbooks("Try2").Sheets("Output").Activate
Workbooks("Try2").Sheets("Output").Cells(k, 2).PasteSpecial xlPasteValues
Range(Cells(k, 1), Cells(k + 10000, 1)) = Country
finalrow2 = 10002 + k
k = finalrow2 + 1
Workbooks(Country).Sheets("Main").Activate
Workbooks(Country).Close SaveChanges:=False
Next i
End Sub
However after consolidating 2-3 files excel it is throwing buffer overflow error. We have around 50 files. I am trying to figure out if this is just a problem with excel unable to handle large files or there is something wrong with my code. Is there any way to guide excel to handle larger files sizes?
There's a couple of things here that could be throwing your macro off.
First, you're declaring i, j, and k as the 'integer' data type; problem with that is that the largest possible value an integer can hold is 32,767. If you go above that, you're going to get a buffer overflow.
Second, you're declaring variables that you don't use, and not declaring variables that you do use. As far as I can see, j isn't used anywhere in the code, but finalrow and finalrow2 are used but aren't declared anywhere.
I would suggest you replace your integer data types that could go very high with long data types (long integer). You might also want to use more descriptive names for your integers to make your code easier to read:
Dim iCycler as integer
Dim kStart as long
Dim FinalRow as Long
Dim FinalRow2 as Long
Run through that and see what you get.
EDITED TO ADD:
Here is a complete process that should suit you:
Sub Duplicator()
'Define the source file, sheet, and range
Dim wbkSource As Workbook
Dim shtSource As Worksheet
Dim rngSource As Range
'Define the target file, sheet and range
Dim wbkTarget As Workbook
Dim shtTarget As Worksheet
Dim rngTarget As Range
'Define the sheet with the list of countries
Dim shtControl As Worksheet
'Prepare control integers
Dim iLoop As Integer
Dim lLastRow As Long
'Define the target file as the active workbook
Set wbkTarget = ActiveWorkbook
Set shtTarget = wbkSource.Sheets("Output")
Set rngTarget = shtTarget.Range("A2")
Set shtControl = wbkTarget.Sheets("Names")
'Loop through the list
For iLoop = 1 To 50
'Open the source file and assign it to a variable.
Set wbkSource = Workbooks.Open("C:\path\" & shtControl.Cells(iLoop, 1).Value)
'Assign the source sheet
Set shtSource = wbkSource.Sheets("Main")
'Find the last row of data
lLastRow = shtSource.Range("A" & Rows.Count).End(xlUp).Row
'Use the last row to build a source range variable
Set rngSource = shtSource.Range("A1", "BL" & lLastRow)
'Check that there is space for the copy. If there is not, create a new sheet for the new data
If rngTarget.Row + lLastRow > shtTarget.Rows.Count Then
Set shtTarget = wbkTarget.Sheets.Add
shtTarget.Name = "Output 2"
Set rngTarget = shtTarget.Range("A2")
End If
'Use the size of rngSource to define the size of the target range
Set rngTarget = rngTarget.Resize(rngSource.Rows.Count, rngSource.Columns.Count)
'Duplicate the values over
rngTarget.Value = rngSource.Value
'Prepare the target range for the next loop
Set rngTarget = shtTarget.Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
'Close the source file
wbkSource.Close False
Next iLoop
End Sub
By declaring and using variables throughout, the code should be easier both to write and to read. It should also run quicker, since it's using the range1.value = range2.value structure, which bypasses the rather slow clipboard. It also contains a check to make sure that you're not surpassing 1,048,576 rows of data, which would cause a crash.
quite along the lines of good coding practice Werff already explained to you, you could try this other (commented) code:
Sub Macro1()
Dim outputSht As Worksheet '<--| declare a variable to set your "output" sheet to
Dim countryData As Variant, countryNames As Variant '<--| declare arrays to store "country names" and "country data" in
Dim country As Variant '<-- "countries" looping variable
Application.Calculation = xlCalculationManual '<-- disable calculations
Application.ScreenUpdating = False '<-- disable screen updating
With Workbooks("Try").Worksheets("Names") '<--| reference "country names" worksheet
countryNames = Application.Transpose(.Range("A1", .Cells(.Rows.count, 1).End(xlUp)).Value) '<--| store country names in column "A" from row 1 down to last not empty row
End With
Set outputSht = Workbooks("Try").Worksheets("Output") '<--| set "output" worksheet
For Each country In countryNames '<-- loop through countries stored in 'countryNames'
With Workbooks.Open(FileName:="C:path\" & Country).Sheets("Main") '<--| open current country workbook and reference its "Main" sheet
countryData = .Range("BL1", .Cells(.Rows.count, 1).End(xlUp)).Value '<--| store current country data in 'countryData' array
.Parent.Close SaveChanges:=False '<--| close current country workbook
End With
With outputSht '<--| reference output sheet
With .Cells(.Rows.count, 1).End(xlUp).Offset(1).Resize(UBound(countryData, 1)) '<--|reference its column A range from first empty cell after last not empty cell down to as many rows as current country array has
.Value = country '<--| write current country name in referenced range
.Offset(, 1).Resize(, 64).Value = countryData '<--| write country data array content from column B rightwards
End With
End With
Next country
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
since it uses arrays to store data, it suffers from the arrays maximum size limitation to 65536 rows. If your "countries" workbooks "Main" sheets have more rows than such a limit then different pasting values techniques must be adopted (like between range values)

excel vba convert string to range

I am trying to run a macro on 3 different ranges, one after another. Once the range is selected, the code works just fine (where variables F and L are defined). I would like to set r1-r3 as Ranges I need and then use a string variable to concatenate the range numbers together. This code works, but doesn't provide the starting and ending row number in the range selected. This is vital because it tells the "TableCalc" macro when to start and stop the code. I would then like to move on to the next range. Thanks for your help.
Sub TestRangeBC()
WS.Select
Dim r1 As Range
Dim r2 As Range
Dim r3 As Range
Dim rngx As String
Dim num As Integer
Dim rng As Range
Set r1 = WS.Range("ONE")
Set r2 = WS.Range("TWO")
Set r3 = WS.Range("THREE")
For num = 1 To 3
rngx = "r" & num
Set rng = Range(rngx)
Dim F As Integer
Dim L As Integer
F = rng.Row + 1
L = rng.Row + rng.Rows.Count - 2
Cells(F, 8).Select
Do While Cells(F, 8) <> "" And ActiveCell.Row <= L
'INSERT SITUATIONAL MACRO
Call TableCalc
WS.Select
ActiveCell.Offset(1, 0).Select
Loop
Next num
End Sub
This is not the answer (as part of your code and what you are trying to achieve is unclear yet), but it is a "cleaner" and more efficient way to code what you have in your original post.
Option Explicit
Dim WS As Worksheet
Your original Sub shorten:
Sub TestRangeBC()
' chanhe WS to your Sheet name
Set WS = Sheets("Sheet1")
Call ActiveRange("ONE")
Call ActiveRange("TWO")
Call ActiveRange("THREE")
End Sub
This Sub gets the Name of the Named Range (you set in your workbook) as a String, and sets the Range accordingly.
Sub ActiveRange(RangeName As String)
Dim Rng As Range
Dim F As Integer
Dim L As Integer
Dim lRow As Long
With WS
Set Rng = .Range(RangeName)
' just for debug purpose >> to ensure the right Range was passed and set
Debug.Print Rng.Address
F = Rng.Row + 1
L = Rng.Row + Rng.Rows.Count - 2
lRow = F
' what you are trying to achieve in this loop is beyond me
Do While .Cells(F, 8) <> "" And .Cells(lRow, 8).Row <= L
Debug.Print .Cells(lRow, 8).Address
'INSERT SITUATIONAL MACRO
' Call TableCalc
' not sure you need to select WS sheet again
WS.Select
lRow = lRow + 1
Loop
End With
End Sub
What are you trying to test in the loop below, what are the criteria of staying in the loop ?
Do While Cells(F, 8) <> "" And ActiveCell.Row <= L
it's really hard to tell what you may want to do
but may be what follows can help you clarifying and (hopefully) doing it!
first off, you can't "combine" variable names
So I'd go with an array of named ranges names (i.e. String array) to be filled by means of a specific sub:
Function GetRanges() As String()
Dim ranges(1 To 3) As String
ranges(1) = "ONE"
ranges(2) = "TWO"
ranges(3) = "THREE"
GetRanges = ranges
End Function
so that you can clean up your "main" sub code and keep only more relevant code there:
Sub TestRangeBC()
Dim r As Variant
Dim ws As Worksheet
Set ws = Worksheets("Ranges") '<--| change "Ranges" to your actual worksheet name
For Each r In GetRanges() '<--| loop through all ranges names
DoIt ws, CStr(r) '<--| call the range name processing routine passing worksheet and its named range name
Next r
End Sub
the "main" sub loops through the named ranges array directly collected from GetRanges() and calls DoIt() to actually process the current one:
Sub DoIt(ws As Worksheet, rangeName As String)
Dim cell As Range
Dim iRow As Long
With ws.Range(rangeName) '<--| reference the passed name passed worksheet named range
For iRow = .Rows(2).Row To .Rows(.Rows.Count - 2).Row '<--| loop through its "inner" rows (i.e. off 1st and last rows)
Set cell = ws.Cells(iRow, 8) '<--| get current row corresponding cell in column "F"
If cell.value = "" Then Exit For '<--| exit at first blank column "F" corresponding cell
TableCalc cell '<-- call TableCalc passing the 'valid' cell as its parameter
Next iRow
End With
End Sub

Excel moving data from one sheet to another and placing in next empty row

I have values coming from a table that i am trying to write a VBA macro for to move to another sheet where it will be place in the next empty row,
here is what i have so far as far as selecting the data goes:
'storing the values to be moved
Dim DayID As String
Dim Shift As Integer
Dim Operator As String
Dim Operation As String
Dim PartNum As String
Dim Asset As String
'placing selected cells
Sheets("Raw Data").Select
Range("A10000").Select
Selection.End(xlUp).Select
ActiveCell.Offset(1, 0).select
ActiveCell.Value = DayID
I got to this point to see if what i had worked with just putting the date in ad it did not. I am new to VBA and don't fully understand what i am doing yet so any help is appreciated!
the columns I'm placing the data in are in columns A, M, O, Q, N, and P respectively if that helps
This assumes that you are working on the same workbook that contains the code. If not, you can change "ThisWorkbook" to "ActiveWorkbook". I included the With wsTarget even though it is currently excessive, with the belief that as you build this subroutine up, it will become increasingly relevant. Edited to place the first three variables into their appropriate columns. I leave it to you to fill in the remaining code:
Sub FirstStep()
'storing the values to be moved
Dim DayID As String
Dim Shift As Integer
Dim Operator As String
Dim Operation As String
Dim PartNum As String
Dim Asset As String
Dim wsTarget As Worksheet
Set wsTarget = ThisWorkbook.Worksheets("Raw Data") 'Would be much better to change the CodeName of the sheet and reference directly.
'placing selected cells
With wsTarget
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = DayID
.Cells(Rows.Count, 13).End(xlUp).Offset(1, 0).Value = Shift
.Cells(Rows.Count, 15).End(xlUp).Offset(1, 0).Value = Operator
End With
End Sub
Without fully knowing what values you want to fill in, what sheet you are starting with and how exactly you want the results to look, something like the following should at least get you started.
Sub test()
Dim rData As Worksheet
Dim lRow As Long
Dim arr(5) As Variant
Set rData = Sheets("Raw Data")
arr(0) = "A"
arr(1) = "M"
arr(2) = "O"
arr(3) = "Q"
arr(4) = "N"
arr(5) = "P"
With rData
For Each element In arr
lRow = .Cells(.Rows.Count, element).End(xlUp).Row + 1
.Cells(lRow, element).Value = "Value in Column " & element
Next element
End With
End Sub