Why is my auto fill not working? - vba

Hoping you can help with the below, I've no idea why this isn't working and I can't seem to figure it out. After some Googling, I can't even find another example of this issue.
Essentially the code should take data on one page, place HLOOKUPS in another page to sort everything into the right columns (all working fine). Then once that's done, it should auto fill down using the row count.
The problem I have, is that it is auto filling on the wrong sheet (it might be worth calling out that the sheet it fills is the same one the code is in and where the rowcnt is.
I tried to explicitly call out the sheet I want to use as such: Range("A2:V2").AutoFill Destination:=Sheets(5).Range("A3:V" & rowcnt), Type:=xlFillDefault but this then throws an Application-defined or object-defined error on the fill line of code.
Public Sub FormatData()
rowcnt = Application.WorksheetFunction.CountA(Sheet4.Range("B:B")) + 1
With Sheets("Final Datasets")
.Cells(2, "A").FormulaR1C1 = _
"=HLOOKUP(""oOrder_date"",'Teradata Downloads'!R1:R1048576,ROW('Final Datasets'!RC),0)"
[snip] load more of the same as above [/snip]
'FILL
Range("A2:V2").AutoFill Destination:=Range("A3:V" & rowcnt), Type:=xlFillDefault
End With
End Sub
I'm properly puzzled here, so any help you can give as to how to fix this (and more importantly, why it's happening) would be greatly appreciated.

if you have the AutoFill in the With Statement, try to use the "." before the Range.
.Range("A2:V2").AutoFill Destination:=.Range("A3:V" & rowcnt)

Related

Excel macro to normalize data

I am currently trying to create a macro for Excel in which a column containing certain values (numbers basically) will be displayed in a new column in a normalized way (highest number = 1, lowest number = 0).
Usually, I would just use the formula:
=(J2-MIN($J$2:$J$XXX))/(MAX($J$2:$J$XXX)-MIN($J$2:$J$XXX))
However, as the length of the column is dynamic and will change for each set of values, I cannot enter a value for XXX.
Now, I found out how to have a dynamic range (e.g.: numRows = Range(Selection, Selection.End(xlDown)).Rows.Count) but I did not manage to merge both functions.
I found a thread already in this site about normalization of data but I think it was a bit of a different story and this one here should be simpler.
I would appreciate any help! As I just started working with macros (2h ago) I would also appreciate if this will be in simple language.
EDIT:
First of all, thanks for the quick reply!
I naively tried making it work with this code:
Sub Normalize_TEST()
'
' Normalize_TEST Makro
'
'
Range("A1").Select
numRows = Range(Selection, Selection.End(xlDown)).Rows.Count
Range("K2").Select
ActiveCell.FormulaR1C1 = "=(("J2")-MIN($J$2:$J$numRows$))/((MAX($J$2:$J$numRows$)-MIN($J$2:$J$numRows$))
Range("K2").Select
Selection.AutoFill Destination:=Range(Cells(2, 11), Cells(numRows, 11))
End Sub
But it is not working and I get an error message ("error of compiling").
I just realize now that you are absolutely right, I don't even need VBA. Your line of =(J2-MIN($J:$J))/(MAX($J:$J)-MIN($J:$J)) works fine. I wasn't aware that with $j:$J it realizes to not include empty cells.
I simply used this code now for cell K2 and then did a VBA autofill function for the rest.
I think this can be closed.
Thank you #tigeravatar for your super quick help!

1004 error when trying to run a macro that applies to a table

I have an existing table. I want to add a new column next to it, with a formula in it so that the formula adds a new column and fills in all the values.
This is a two-page worksheet. Table1 is on another page than the table we're working with, but has the master data it draws from.
I recorded a macro of the formula I used to produce this, but when I try to run it, I get
Run time error '1004': Application-defined or object-defined error.
The code I'm using is below:
Range("B2").Select
ActiveCell.FormulaR1C1 = "=IF(INDEX(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Status"",Table1[#Headers],0))=""for sale"",""seller""," & _
"IF(INDEX(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Status"",Table1[#Headers],0))=""for lease"",""landlord""," & _
"IF(INDEX(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Status"",Table1[#Headers],0))=""for sale or lease"",""seller / landlord""" & _
"X(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Base Rent/Mo"",Table1[#Headers],0))>0,""landlord"",""seller""))))"
Range("B1").Select
Things I've checked so far:
All the names match (i.e. Table1 is a valid name, and all the headers are correctly named)
The formula works exacly as I want to if I just type it in and hit 'enter'
I've looked for similar issues here, and the most similar seem to be some problems with Pivot tables, but the solutions don't seem to be applicable to my problem
(The reason I'm using VBA for this is that this is one part of a multi-step process that I'm trying to automate to make it simpler to run a complicated report from a large set of data.)
EDIT: Additional fixes I tried:
Moving the master data table to the same sheet as my 'target' table to see if it would work if the two were on the same worksheet. No go.
When you need to use quotes inside quotes like in "MATCH(""Status"", which I suppose you are trying to output Match("Status" try using "MATCH("&Chr(34)&Status&Chr(34)
Chr(34) outputs the " symbol. Otherwise it would return MATCH(Status (without quotes)
There were two separate issues.
First, I was recording the macro and apparently, Excel will not record formulas longer than a certain length properly. This limit is greater than 407 (the longest formula I got to auto capture), but shorter than 467 characters. A similar problem was discussed on this Mr. Excel post. This also was why part of the "INDEX" was missing, as BruceWayne pointed out.
In addition, it was necessary to switch from .FormulaR1C1 to .Formula to get it to work correctly, as R3uK had suggested.
The final code ended up as follows:
Range("B2").Select
ActiveCell.Formula = _
"=IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Status"",Table1[#Headers],0))=""for sale"",""seller"",IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Status"",Table1[#Headers],0))=""for lease"",""landlord"",IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Status"",Table1[#Headers],0))=""for sale or lease"",""seller / landlord"",IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Base Rent/Mo"",Table1[#Headers],0))>0,""landlord"",""seller""))))"
Range("B3").Select

Two methods of selecting sheet2 and finding the last used row using a command button in sheet1 both fail

I have been trying to select Sheet2 from Sheet1 using a command button click macro. The final part of the macro is designed to find the last used row (offset by 1) and return the row number using MsgBox. I have tried two methods of selecting sheet2. However, in both cases the number returned by MsgBox is the last used row of sheet1, not of sheet2. I know this because when I change the last cell in column A that contains data (i.e. place data in a different cell), the MsgBox provides the new value (offset by 1).
I guess the error may be in my usage of Cells.Find. I know that there are several possible methods of determining the last used row but from what I’ve read the Cells.Find method is the most reliable. The only obvious thing to me is that the row number returned is from Sheet1, not Sheet2. There are no error messages associated with this failure.
The first method is:
Private Sub CommandButton1_Click()
Set wSheet = Worksheets("Sheet2")
wSheet.Activate
With wSheet
unusedRow = Cells.Find("*", [A1], , , xlByRows, xlPrevious).Offset(1, 0).Row
End With
MsgBox (unusedRow)
End Sub
The second method is:
Private Sub CommandButton1_Click()
Application.Goto Reference:=Worksheets("Sheet2").Range("A1"), Scroll:=True
unusedRow = Cells.Find("*", [A1], , , xlByRows, xlPrevious).Offset(1, 0).Row
MsgBox (unusedRow)
End Sub
Can anybody comment on any errors in my code? Any help would be greatly appreciated. I am very much a learner of XL VBA.
Edit: Response to comments
Thanks a lot #Dan; I have read both of those works you referenced. There is another useful discussion I found that I will dig out the link for and put here. I think I'm not yet tuned to the syntax at even a fairly fundamental level, so some of the more subtle variations are still a bit obscure. But I have got the point about avoiding select etc although I can only get there sometimes. I guess that's because I quite often use the macro recorder which tends to use the select family.
Many thanks #Tony - that's the piece of information I needed - the macro works fine now and I understand things a little better. Yes, I did run it with the Activate statement included and it gave me the last used row (offset by 1) for Sheet1; with your revision I get that row number for Sheet2. Thanks again.

Run time error '1004' Unable to get the Match propertyof the WorksheetFunction class

In my macro, I have the following code :
i = Application.WorksheetFunction.Match(str_accrual, Range(Selection, Selection.End(xlToRight)), 0)
where 'str_accrual' is a string captured earlier to this line and the Range selected is in a single row say from "A1" to "BH1" and the result will be a number which is the position of that string in that range selected.
When I run the macro, I get the error:
Run time error '1004' Unable to get the Match propertyof the WorksheetFunction class
But when I run the macro line by line using (F8) key, I don't get this error but when I run the macro continuously I get the error. Again, if the abort the macro and run it again the error doesn't appear.
I tried several times. It seems that if there is no match, the expression will prompt this error
if you want to catch the error, use Application.Match instead
Then you can wrap it with isError
tons of posts on this error but no solution as far as I read the posts. It seems that for various worksheet functions to work, the worksheet must be active/visible. (That's at least my latest finding after my Match() was working randomly for spurious reasons.)
I hoped the mystery was solved, though activating worksheets for this kind of lookup action was a pain and costs a few CPU cycles.
So I played around with syntax variations and it turned out that the code started to work after I removed the underscore line breaks, regardless of the worksheet being displayed. <- well, for some reason I still had to activate the worksheet :-(
'does not work
'Set oCllHeader = ActiveWorkbook.Worksheets("Auswertung").Cells(oCllSpielID.Row, _
Application.Match( _
strValue, _
ActiveWorkbook.Worksheets("Auswertung").Range( _
oCllSpielID, _
ActiveWorkbook.Worksheets("Auswertung").Cells(oCllSpielID.Row, lastUsedCellInRow(oCllSpielID).Column)), _
0))
'does work (removed the line breaks with underscore for readibility) <- this syntax stopped working later, no way around activating the worksheet :-(
Set oCllHeader = ActiveWorkbook.Worksheets("Auswertung").Cells(oCllSpielID.Row, Application.Match(strValue, ActiveWorkbook.Worksheets("Auswertung").Range(oCllSpielID, ActiveWorkbook.Worksheets("Auswertung").Cells(oCllSpielID.Row, lastUsedCellInRow(oCllSpielID).Column)), 0))
In the end I am fretting running into more realizations of this mystery and spending lots of time again.
cheers
I was getting this error intermittently. Turns out, it happened when I had a different worksheet active.
As the docs for Range say,
When it's used without an object qualifier (an object to the left of the period), the Range property returns a range on the active sheet.
So, to fix the error you add a qualifier:
Sheet1.Range
I had this issue using a third-party generated xls file that the program was pulling from. When I changed the export from the third-party program to xls (data only) it resolved my issue. So for some of you, maybe there is an issue with pulling data from a cell that isn't just a clean value.
I apologize if my nomenclature isn't great, just a novice to this.
That is what you get if MATCH fails to find the value.
Try this instead:
If Not IsError(Application.Match(str_accrual, Range(Selection, Selection.End(xlToRight)), 0)) Then
i = Application.Match(str_accrual, Range(Selection, Selection.End(xlToRight)), 0)
Else
'do something if no match is found
End If
Update
Here is better code that does not rely on Selection except as a means of user-input for defining the range to be searched.
Sub Test()
Dim str_accrual As String
Dim rngToSearch As Range
str_accrual = InputBox("Search for?")
Set rngToSearch = Range(Selection, Selection.End(xlToRight))
If Not IsError(Application.Match(str_accrual, rngToSearch, 0)) Then
i = Application.Match(str_accrual, rngToSearch, 0)
MsgBox i
Else
MsgBox "no match is found in range(" & rngToSearch.Address & ")."
End If
End Sub
I used "If Not IsError" and the error kept showing. To prevent the error, add the following line as well:
On Local Error Resume Next
when nothing is found, Match returns data type Error, which is different from a number. You may want to try this.
dim result variant
result = Application.Match(....)
if Iserror(result)
then not found
else do your normal thing

Removing Charts in Excel

I was trying to chart some RTD data and accidentally ended up with hundreds of charts on the same worksheet. Now I'm trying to undo my error and remove all of the charts but I'm not having much luck with it.
I recorded a macro where I deleted one of the charts manually and then tried editing the code to loop through all of the charts but I keep getting an error. My code is below:
Sub Macro3()
Dim i As Integer
For i = 1 To 100
Sheets("Calculations").Select
ActiveSheet.ChartObjects("Chart " & CStr(i)).Activate
ActiveChart.ChartArea.Select
ActiveWindow.Visible = False
Selection.Delete
Next i
End Sub
When I try running this, I get an error saying that the ChartObjects property was inaccessible from the Worksheet class.
I'm sure there's a simple explanation/solution to this but I've learned that VBA sometimes does things a little differently than you might be expecting. So, I guess my question is, how do I remove the charts without having to go through each one at a time?
Any help would be appreciated. Thanks.
Try this, it will get rid of all charts on your sheet regardless of their names.
Sub Macro3()
Worksheets("Calculations").ChartObjects.Delete
End Sub
It's quite possible you are attempting to access a chart by name which no longer exists. Try accessing the charts by index using ChartObjects(i) instead.