I believe I'm having an issue with either appropriately identifying a fixed cell or order of operations. I've spent an hour an a half researching and can't find the answer. The issue is only with the Concatenation row: I can't get VBA to recognize the insertion of a fixed cell into the text of the formula (I can only get it R the cell). It's for a daily exported excel report from a database that inserts the date into C2. I'm concatenating the file names in column B with the folder location they'll be in at the end of the day, the day's date and the unique file group identifier in each matching cell in column C. I've replaced the text of the folder name with FOLDER for confidentiality purposes. I can concatenate and autofill it manually, but I'd rather just type the formula in once! Any assistance would be helpful.
Thanks! - John
Columns("A:A").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("C2").Select
ActiveCell.FormulaR1C1 = "=TEXT(RC[-1],""yyyy mm dd"")"
Range("C2").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveSheet.Paste
Application.CutCopyMode = False
Range("A5").Select
ActiveCell.FormulaR1C1 =
"=CONCATENATE(""FOLDER,("$C$2"), FOLDER"",RC[1])"
Dim lastRow As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("A5").Select
Selection.AutoFill Destination:=Range("A5:A" & lastRow), Type:=xlFillDefault
Range("A5:A" & lastRow).Select
Selection.Copy
Range("B5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Columns("A:A").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Rows("1:2").Select
Selection.Delete Shift:=xlUp
Range("B3").Select
I don't know if this will work since the formula is expecting references via the RC notation, but you could try:
ActiveCell.FormulaR1C1 =
"=CONCATENATE(""FOLDER,(" & "$C$2" & "), FOLDER"",RC[1])"
As an alternative to inserting a fixed cell, an option would be to assign that cell's value to a string variable and than insert that.
Dim dateVal as string
dateVal = Range("C2").Value2
Range("A5").FormulaR1C1 =
"=CONCATENATE(""FOLDER,(" & dateVal & "), FOLDER"",RC[1])"
Related
I'm setting up a pricing model and am wondering how I am able to get the macro to run the pricing loan by loan and have the output pasted in a separate tab (this would also be loan by loan, so it cannot overwrite). I used the macro recorder and this is what I have so far, but I'm a novice and not sure how to loop this until it hits a blank cell (I did the first two loans....)
Sub Macro1()
'
' Macro1 Macro
'
'
Selection.Copy
Sheets("Cashflows").Select
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range(Selection, Selection.End(xlToRight)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Output").Select
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Input").Select
Range("A3").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Cashflows").Select
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range(Selection, Selection.End(xlToRight)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Output").Select
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
The tools you need:
To figure out the last row:
Dim LastRow As Integer
LastRow = Range("A" & Rows.Count).End(xlUp).Row
'This simulates selecting the last cell in "A" Column,
'hitting "End" and "Up Arrow", then returns that row number
'as in integer.
To cycle through each row:
Dim I As Integer
For I = 1 To 10 '(Or replace "10" with "LastRow")
'Do something like look at a range value:
Debug.Print Cells(I, 1).Value
Next I
Finally, this is going to be a lot easier if you use .value = .value instead of copying and pasting:
Dim RowNum As Integer
RowNum = 10
Range("A1").Value = Range("B1").Value 'Copies Value from B1 into A1
Cells(1, 1).Value = Range("B1").Value 'Does Exact same thing as above: Cells(row, column)
'Copy A10:C10 from sheet2 to sheet1:
Sheet1.Range("A" & RowNum & ":C" & RowNum).Value = Sheet2.Range("A" & RowNum & ":C" & RowNum)
See how far you get with that and come back if you have more specific questions.
There are lots of good resources out there if you're having trouble.
My file has four sheets.
From all of them, I want to copy and paste column A (from A:10) (which contains a concat formula) when some other rows are populated and then save into a csv.
All rows from A10 onwards have the concat formula which is then filled in depending on the other columns (the same applies for the other sheets).
I have it currently creating sheet1, and pasting there, then saving as a csv.
However, from the first sheet it looks at, it takes only the first line (but the second line - J11 (and so A11) are populated.
In the other sheets, it is copy and pasting the 2 rows that are populated, but also all the other rows as there are formulas there that return zero.
As I have the .End(xlDown) and technically all the other rows are populated.
I tried an IF statement for the last sheet only as a test, and currently it only copies the first populated line, and not the second (but at least it also doesn't copy all the other cells with zero).
Essentially, for each sheet I'd like to loop through with for example E10 is populated, copy and paste A10 into Sheet1, etc., if E10 is not zero.
Sub Output_test1()
'
' Output_test1 Macro
'
'
Sheets("Create").Select
Range("A10", Range("J10").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets.Add.Name = "Sheet1"
Sheets("Sheet1").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Assign").Select
Range("A10", Range("E10").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("A1").End(xlDown).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Date & Time").Select
Range("A10", Range("E10").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("A1").End(xlDown).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Event Type").Select
Dim rg As Range
For Each rg In Range("E10").End(xlDown)
If rg.Value > 0 Then
End If
Range("A10").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("A1").End(xlDown).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Application.CutCopyMode = False
Next
Sheets("Sheet1").Move
myTime = Format(Now, ("dd.mm.yy"))
ChDir "C:\Users\"
ActiveWorkbook.SaveAs Filename:= _
"Recruit_" & myTime & ".csv", FileFormat:=xlCSVUTF8, _
CreateBackup:=False
End Sub
There is no loop in your code not are you checking any values. I assumed you need to check column J in the source sheet and copy column A to the destination sheet.
This is a possible starting point:
k = 1
For i = 10 to 20
If Sheets("Source").Range("J" & i).Value = 0 then
Sheets("Destination").Range("A" & k).Value = Sheets("Source").Range("A" & i).Value
k = k + 1
End if
Next i
This only copies the value, not the formula. Not sure how much to explain, comment on the answer if any questions
I have following code
First it will insert two columns one by one
Then count rows in C column
Then Copy ActiveCell.FormulaR1C1 = "=R[-5]C[18]" to B7 to rows count
Similarly, Copy ActiveCell.FormulaR1C1 = "=R[-5]C[13]" to A7 to rows count
But I am getting error when the Active Row is only 01 (One), if it is more than one then it works ok.
I am struggling with this. If anyone can please help.
Columns("A:A").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Columns("A:A").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Dim LastRow As Long
LastRow = Range("C" & Rows.Count).End(xlUp).Row
Range("B7").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=R[-5]C[18]"
Range("B7").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("B7:B" & LastRow), Type:=xlFillCopy
Range("B7:B" & LastRow).Select
Range("A7").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=R[-5]C[13]"
Range("A7").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A7:A" & LastRow), Type:=xlFillCopy
Range("A7:A" & LastRow).Select
To close the question out:
Instead of using AutoFill, maybe do Range("B7:B" & LastRow).Value = Range("B7").Value, and similarly for column A.
Or just in one line for both columns: Range("A7:B" & LastRow).Value = Range("A7:B7").Value.
First off, the Selection object is not necessarily the best option. You can insert the columns with Range("A:B").Insert xlShiftToRight.
Next, you can set the formula for an entire range at once rather than copying and pasting. Since you're putting the formulas only starting at row 7, you'll need to offset and resize the range that is defined by what is in Column C (after the insert).
The Resize method will need to reduce the row count by 6 since the formulas don't start until row 7:.Resize(LastRow - 6). Since the original range is only one column wide, the column count in the Resize method can be omitted (otherwise, it'd be .Resize(LastRow - 6, 1)).
The Offset method will need to shift down 6 rows and left 1 (or 2) columns: .Offset(6,-1) and .Offset(6,-2)).
Your code would then be greatly simplified to:
Dim LastRow As Long
ActiveSheet.Range("A:B").Insert xlShiftToRight
LastRow = Range("C" & Rows.Count).End(xlUp).Row
With Range("C:C").Resize(LastRow-6)
.Offset(6,-1).FormulaR1C1="=R[-5]C[18]"
.Offset(6,-2).FormulaR1C1="=R[-5]C[13]"
End With
Of course, even easier would be to convert your sheet to a Table ("ListObject" in VBA) and let Excel do the heavy lifting. But that's way outside what you asked.
Most of our orders go through our original packing team who use this consolidated format for packing orders per customer.
A new team requires each item to be on a separate line, so each Sales Order needs five rows, one for each type of widget we sell. They need it to look like this:
I recorded a macro of the copy/paste commands to log the first order:
Sub GrabOrders()
'
' GrabOrders Macro
'
'
Sheets("Raw Data").Select
Range("B2").Select
Selection.Copy
Sheets("Ship Sheet").Select
Range("A2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A2:A6"), Type:=xlFillDefault
Range("A2:A6").Select
Sheets("Raw Data").Select
Range("F1:J1").Select
Selection.Copy
Sheets("Ship Sheet").Select
Range("G2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("Raw Data").Select
Range("F2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Ship Sheet").Select
Range("H2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
End Sub
I now need the cell-to-be-copied (on the original format tab) to move down one row to the next order and for the pasting on the new format tab to begin five rows down so as not to overwrite data from the previous order.
The Item Name will remain fixed (in F1, G1, etc. on the original tab) while the other cells-to-be-copied will be moving. I need this to loop until it reaches a blank Sales Order cell.
You should start by removing all of the select statements in your code.
Range("B2").Select
Selection.Copy
Can be simplified to
Sheets("Raw Data").Range("B2").Copy
When you are writing loops you need to start by defining the range in which your data will be located. You will learn more about how to do this when you read about avoiding select statements. You're going to want to want to define the range for the data which you pull from and to avoid rewriting your code I'll define another last row within the loop to account for the autofill command you have opted to use.
The below I believe works for what you are trying to achieve but you should try to go back and remove the select statements.
Sub GrabOrders()
Dim lrdata As Long
lrdata = Sheets("Raw Data").Range("A" & Rows.Count).End(xlUp).Row ' choose whichever column contains the last row of your data here
Dim i As Long
For i = 2 To lrdata ' for 2 to the number of rows in our data
Dim lastrow2 As Long
lastrow2 = Sheets("Ship Sheet").Range("a" & Rows.Count).End(xlUp).Row + 1 ' get the last row in your ship sheet then add one to avoid copying over your data
' from here, every instace of "2" you are going to change it to " & i "
Sheets("Raw Data").Select
Sheets("Raw Data").Range("B" & i).Select
Selection.Copy
Sheets("Ship Sheet").Select
Sheets("Ship Sheet").Range("A" & lastrow2).Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A" & lastrow2, "A" & lastrow2 + 4), Type:=xlFillDefault ' plus five to your last row since there are only 5 colors you need to get data for
Sheets("Raw Data").Select
Range("F1:J1").Select
Selection.Copy
Sheets("Ship Sheet").Select
Range("G" & lastrow2).Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("Raw Data").Select
Sheets("Raw Data").Range("F" & i, "J" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Ship Sheet").Select
Sheets("Ship Sheet").Range("H" & lastrow2).Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Next i
End Sub
I am setting up a attendance spreadsheet where we count the total Late and sick days using the CountIf function. Employees are listed one per column. I am trying to write a macro that will count the number of late or sick days per employee, enter that value to a cell and copy that value to a summary sheet. Then using a For Loop to iterate through each employee using the same range (number of rows) but always moving over one column.
This is my first time really using VBA so I am stuck as my code gives me an error when trying to iterate up the columns.
Thank you!
Sub Counting()
ActiveCell.Select
ActiveCell.Offset(0, -1).Range("A1").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(R[-10]C[2]:RC[2],""L"")"
Selection.Copy
Sheets("Sheet3").Select
Range("B2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,
SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Application.CutCopyMode = False
Selection.ClearContents
Dim LastCol As Integer
With ActiveSheet
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
Dim i As Integer
For i = 1 To LastCol
ActiveCell.FormulaR1C1 = "=COUNTIF(R[-10]C[i]:RC[i],""L"")"
ActiveCell.Select
Selection.Copy
Sheets("Sheet3").Select
ActiveCell.Offset(1, 0).Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,
SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Application.CutCopyMode = False
Selection.ClearContents
Next i
End Sub
The problem is with this line:
ActiveCell.FormulaR1C1 = "=COUNTIF(R[-10]C[i]:RC[i],""L"")"
It looks like you want the value of i in here, not the letter "i", which you can do like this:
ActiveCell.FormulaR1C1 = "=COUNTIF(R[-10]C[" & i & "]:RC[" & i & "],""L"")"
This will fix your immediate error message, however the macro as whole is very fragile, you should read article PEH referenced and replace all those .Select / .Copy / .PasteSpecial as much as possible.
Alternatively, you can probably do what you need without a macro, and use formulas instead. If you can it would be preferable.