I am trying to convert the used range of a column to hourly data using floor.
As a function in Excel I have =FLOOR(A2, "1:00")
So 2016-07-01 07:59:59.0000000 would become 01-07/2016 7:00
I would like to do this in VBA for just Column A where the first row is a header. I guess I'd need to convert to dateTime afterwards to but haven't thought about that yet (shouldn't be difficult).
I have tried this:
.Range(Cells(2, 1), Cells(Rows.Count, 1).End(xlUp)) = _
Application.WorksheetFunction.Floor(Cells(2, 1), Cells(Rows.Count, 1).End(xlUp), "1:00")
But get wrong number of arguments error.
This:
.Range("A:A") = Application.WorksheetFunction.Floor("A:A", "1:00")
gives a type mismatch.
Not sure how to proceed.
The WorksheetFunction.Floor Method in VBA is a little different from the worksheets =Floor function:
WorksheetFunction.Floor(Arg1, Arg2)
Both arguments Arg1 and Arg2 need to be of the type double.
So you will need to use 1/24 instead of "1:00" (which is the same because 1 hour is 1/24 of a day) and a value .Cells(i, "A").Value instead of a cell reference name "A:A".
Also you will need a loop to achieve it for every used cell in the whole column A.
Option Explicit 'First line at your module ensures you declare any variables
Public Sub FloorFormat()
Dim lastRow As Long
With Worksheets("Sheet1") 'Your sheet name here
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row 'find last used row
Dim i As Long
For i = 1 To lastRow 'do the following for all used rows in column A
.Cells(i, "A").Value = Application.WorksheetFunction.Floor(.Cells(i, "A").Value, 1 / 24)
Next i
End With
End Sub
Related
VBA question using Excel 2016 (64 bit)
I have header data in the first two columns (A:B) and the top row (1). I would like to dynamically paste a formula downward, starting from cell C2, to the last row and the last column. The working prototype is as follows:
Dim LstCol As Long
LstCol = Cells(1, Columns.Count).End(xlToLeft).Column
Range(Cells(2, "C"), Cells(2, LstCol)).Value = "=INDEX(RC1,MATCH(R1C,RC2,0))"
Dim LstRow As Long
LstRow = Cells(1, Rows.Count).End(xlUp).Row
Range(Cells(2, "C"), Cells(2, LstRow)).Value = "=INDEX(RC1,MATCH(RC1,R2C,0))"
The first Dim works as intended. The formula is successfully deployed throughout the second row to the final column (or perhaps it starts at the last column and moves leftward). However, the second Dim stops on an error. I'm unsure how to spread the data from the last row (to the last column) upwards to the second row (and the corresponding last column).
In my example, the first two columns have header data from 1 to 5330 (A1:B5330). I also have header data in the first row (C1:AX1). My target is to fill the formula =INDEX($A2,MATCH(D$1,$B2,0)) from C2:AX5330 dynamically.
Where am I going wrong?
You need to properly qualify your instances of Range and Cells with a worksheet. You can either directly do this, dim a worksheet variable, or use a With block like so:
Dim LRow as Long
With ThisworkBook.Sheets("????")
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("C2:AX5330").Formula = "=INDEX($A2,MATCH(D$1,$B2,0))" 'Make sure your cell references are correct here
.Range("C2:AX5330").Value = .Range("C2:AX55330").Value 'Place as values instead of formula
End With
What's the difference between accessing a row's cells these ways:
Sub test6()
Dim wRange As Range
Set wRange = Range("B3:P10")
For Each aRow In wRange.Rows
'need to get this row's second column (B)
Cells(aRow.Row, 4).value = aRow.Cells(1, 2).Address
Cells(aRow.Row, 5).value = Cells(aRow.Row, 2).Address
Next
End Sub
I get weird results, depending on the range. Besides I have a more complex program that also gives different results when using these two methods.
I changed your procedure a bit and added the output of Debug.Print as comment to better explain why this is an expected result:
Option Explicit 'in the first line of your modules: Ensures you need to declare all variables
Sub test6()
Dim wRange As Range, aRow As Variant
Set wRange = Range("B3:P10")
For Each aRow In wRange.Rows
' Outputs of the first loop run:
Debug.Print aRow.Address ' $B$3:$P$3
Debug.Print aRow.Cells(1, 2).Address ' $C$3
Debug.Print Cells(aRow.Row, 2).Address ' $B$3
Next
End Sub
Explanationː
aRow is a sub range ($B$3:$P$3) out of the original range B3:P10 containing only one row (but not an entire row of the worksheet as you assume) so aRow.Cells(1, 2) refers to column 2 relative to aRow which is C because the range is starting with B not with A.
Cells(aRow.Row, 2) is exactly the same as writing ActiveSheet.Cells(aRow.Row, 2) and refers to column 2 relative to the ActiveSheet which is B because the range of the sheet is starting at A.
aRow.EntireRow.Cells(1, 2).Address would be the same as Cells(aRow.Row, 2).Address because now we refer to the entire row starting at column A.
Side note:
I recommend not to assume the worksheet and fully qualify your cells/ranges so you always see to which range the cells are relative to.
Your result isn't weird, because aRow.Cells().Address returns an address, relative to column B, since first column of wRange is B too.
So in your case you need this line instead:
...
'need to get this row's second column (B)
Cells(AROW.Row, 4).Value = AROW.Cells(1, 1).Address
'^ relative index
...
And when you use this property without an object qualifier (simply Cells()) - this gives your a result relative to entire active worksheet!
The RowIndex and ColumnIndex arguments are relative offsets.
Cells(aRow.Row, 4) refers to the cells of the ActiveSheet. aRow.Cells(1, 2) refers to a cell in teh aRow range.
I am dealing with a sheet of data that has multiple rows ans columns. Each time the macro runs, the number of rows can be different, so I am trying to find the last row for a column.
With the last row, I am trying to do a calculation. For example: if the row I get is 1200, I can do A1200/A2-1. MY code should explicitly paste the formula in an output worksheet and currently (currently I have to put the last row myself).
Question: How can I get the last row and put it in a formula? Should I assign it to a variable and then use the variable in the formula?
Lines of code I am using:
Sub Output()
Dim LastRowA As Long
LastRowA = Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Row
'this is my current method, it works using specific cells.
'I would like to change the D1662, for example, for a floating reference that gets the last row
Worksheets("Sheet2").Range("C2:C2").Formula = "='TIME SERIES'!D1662/'TIME SERIES'!D2-1"
End Sub
Like so. Just remove the variable from the quotes.
Sub Output()
Dim LastRowA As Long
LastRowA = Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Row
'this is my current method, it works using specific cells.
'I would like to change the D1662, for example, for a floating reference that gets the last row
Worksheets("Sheet2").Range("C2:C2").Formula = "='TIME SERIES'!D" & LastRowA & "/'TIME SERIES'!D2-1"
End Sub
How about a user defined function? This way you can add it to your equation in excel with =LastRow(ColumnNumber). You can leave this in the vba editor and in excel set you cell value to "=LastRowValue("SheetName",1)/A2-1" where 1 would be column A.
Function LastRowValue(WorksheetName As String, Col As Long) As Long
'=======================================================================
'This can be typed into an excel cell as a normal function
'"=LastRow("SheetName",ColumnNumber)" The Column Number is indexed
'starting with A=1 so C=3 and AA=27. Enter the WorksheetName in
'quotes "WorksheetName".
'========================================================================
Dim LR As Long
'LR will find the last row in column number "col" in WorksheetName.
LR = ThisWorkbook.Sheets(WorksheetName).Cells(Rows.Count, Col).End(xlUp).Row
'LastRowValue will be the output of this function and will be the value of
'the last row in WorksheetName.
LastRowValue = Cells(LR, Col).Value
End Function
http://i.stack.imgur.com/93bt7.png
Hi,
I am trying to work with a code I have made but am having some trouble.
If you look at my photo above, in cell B3 I have a CUSIP. What I want to do is copy that CUSIP and paste it in each row of info for that CUSIP (so rows A4 till A8). Then I want to move to the second CUSIP in J3 (the CUSIPS are all in row 3 and 8 columns apart) and then paste the CUSIP in rows J4 to J35.
I want to keep doing this over and over for 1000 securities but the issue is that the rows differ in length.
My code is working until I get to the last piece of code which I have put in as a comment. It works but is static. Only works for moving from the 1st to 2nd security then fails. I am trying to think of a dynamic way for me to move from the cell which the CUSIP is last pasted in to the third row and corresponding column everytime (column will be 9 apart every time from the last pasted cell).
Here it is:
Sub CUSIP_Copy_Paste()
Dim LastRow As Long
Dim LastCol As Long
Dim c As Long
Dim r As Long
Range("B3").Select
LastCol = Cells(4, Columns.Count).End(xlToLeft).column
For c = 2 To LastCol Step 8
LastRow = Cells(Rows.Count, c).End(xlUp).row
ActiveCell.Copy
Cells(4, ActiveCell.Offset(1, -1).column).PasteSpecial xlPasteValues
For r = 5 To LastRow
Cells(r, ActiveCell.Offset(1, 0).column).PasteSpecial xlPasteValues
Next r
''''''ActiveCell.Offset(-5, 9).Select
Next c
End Sub
Thanks!
Your error lies in the final offset. Instead of -5, put in a variable, preferrably the variable which is the difference between the end of the rows count and the beginning, which is always 3.
That is to say, Offset(3 - lastRow, 9)
You almost had it friendo :)
I am trying to nativate a spreadsheet that has three columns for each month (Jan-Dec). If the month isn't in the past then the third column should sum the other two (otherwise empty). This should be applied from row 6 to LastRow.
My problem is that I can't work out how to correctly use LastRow. It needs to be defined beforehand using a different column that I can reply on not having any missing values.
I have been trying to capture this row in LastRow but I think I must be doing something fundamentally wrong as I get a type mismatch error for set sh.LastRow:
Sub Prep_datadump()
Dim sh As Worksheet
Dim Dataset as Range
Dim LastRow As Range
Dim Month As Integer
Set sh.Dataset.Range("C6:C" & .Range("C" & .Rows.Count).End(xlUp).Row)
Set LastRow = Dataset.End(xlDown).Row
For Month = 14 To 47 Step 3
If Cells(1, Month) >= Date Then
Sh.Range(Cells(6, Month), Cells(LastRow, Month)).FormulaR1C1 = "=sum(RC[-2],RC[-1])"
End If
Next Month
End Sub
The line you are having a problem with (Set LastRow = Dataset.End(xlDown).Row) attempts to assign the row number of the bottom cell in your Dataset range as an integer to your LastRow variable. As you first define LastRow as a Range the code is unable to do this action as it is a different variable type and so you receive the mismatch error.
Try changing your Dim LastRow As Range line to Dim LastRow As Integer