I created a macro which summarizes a series of Excel forms into outputs, organized by sheets, rows and columns. The program creates a sheet, populates a table, and repeats.
The only thing I have left to do is to populate the cells with a formula. It's a very simple AverageIfs formula and I am getting the "Unable to get Averageifs property of WorksheetFunction class" error. I tried a bunch of things that I read, but to no avail.
So far I
Copied and pasted the formula itself into a separate macro (it ran, so it isn't a typo)
Removed the formula and checked to make sure every variable in the formula is the value I expect it to be at this point in the program (each one is)
Here is the relevant excerpt of my code. I am omitting a large portion, but I can assure all variables are defined and the loop works properly if I replace the AverageIfs function with a hard value (e.g. "1").
'Start Loop
VBid = 0
ZEval = 0
Do While VBid <> NumBidder
ActiveBid = ListInputSheet.Range("H" & 7 + VBid).Value
Set AnalysisSheet = AnalysisBook.Sheets.Add
AnalysisSheet.Name = ActiveBid
XRow = 4
AnalysisSheet.Range("C" & XRow).Value = ActiveBid
ZEval = 0
'Loop all evaluators down rows
Do While ZEval <> NumEval
ActiveEval = ListInputSheet.Range("E" & 7 + ZEval).Value
AnalysisSheet.Range("D" & XRow).Value = ActiveEval
AnalysisSheet.Range("D" & XRow).Select
WSub = 0
'Loop all Category Averages across row in columns
Do While WSub <> NumCategories
ActiveCell.Offset(0, 1).Select
Form = Application.WorksheetFunction.AverageIfs(SummarySheet.Range("F1:F10000"), SummarySheet.Range("A1:A10000"), ActiveEval, SummarySheet.Range("B1:B10000"), ActiveBid, SummarySheet.Range("D1:D10000"), WSub + 1)
ActiveCell.Value = Form
WSub = WSub + 1
Loop
XRow = XRow + 1
ZEval = ZEval + 1
Loop
'End evaluator loop
VBid = VBid + 1
Loop
'End Bidder loop
I have encountered the same error and couldn'd find a reason for a while, but later figured out that it is a issue with the data. It seems for the average function we need more than one row of data to work, so when I added additional rows of data it started working fine without any issue.
Here's an alternative if you cannot get it going. Just swap this line of code for you AverageIfs line:
Form = SummarySheet.Evaluate("AverageIfs(F1:F10000,A1:A10000," & ActiveEval & ",B1:B10000," & ActiveBid & ",D1:D10000," & WSub + 1 & ")")
Related
I am trying to automate a process to generate 2 XYScatter graphs from 1 table and seem to be making a mess of it. There are multiple issues I'm hitting so I will try to describe 1 at a time.
The first issue is setting the X & Y ranges. The table could contain anywhere from 4 to a few hundred rows. Column A = X values, column F says if it is level 1/graph 1 or level 2/graph 2, & column J = Y value. I created 4 Range variables, RngL1X, RngL1Y, RngL2X & RngL2Y. Then I wrote some code to loop through column F and fill the data ranges (see below).
What is the correct syntax to make an empty range? Before I can use them, the ranges need to have initial values. I would like to set them to "Empty" but VBA doesn't like any of the syntax I have tried: Set RngL1X = " ", RngL1X = IsNull, RngL1X = IsEmpty, etc.
Here's the loop code for filling the variables. I can't tell how well it will work until I solve the problem of the initial values.
Range("F2").Select
Do While IsEmpty(ActiveCell) = False
If ActiveCell Like "*Level 1*" Then
RngL1X = RngL1X & ", " & ActiveCell.Offset(0, -5)
RngL1Y = RngL1Y & ", " & ActiveCell.Offset(0, 4)
Else
RngL2X = RngL2X & ", " & ActiveCell.Offset(0, -5)
RngL2Y = RngL2Y & ", " & ActiveCell.Offset(0, 4)
End If
Debug.Print RngL2Y
ActiveCell.Offset(1, 0).Select
Loop
When I tested the loop with the variables as a string (not a range) it worked well.
I am new to macros in Excel, and I’m trying to speed up a process. I need to add a varying number of blank rows, if certain text is present in the cell above it. Not equal, but containing.
For example if A1 contains 'Apples', add two blank rows beneath. If A6 has 'Plums', add four blank rows beneath, etc.
What I have now is this:
For a=1 To ActiveSheet.Cells(Rows.Count,1).End(x1Up).Row
If ActiveSheet.Cells(a,1).Value = “Apples” Then
ActiveSheet.Rows(2).Insert
a = a+1
ELSE
If ActiveSheet.Cells(a,1).Value = “Plums” Then
ActiveSheet.Rows(4).Insert
a = a+1
End If
End Sub
So far I've gotten a Compile Error, stating "Block If without End If" though I believe I closed them both. I'm not sure if I'm correctly comparing or searching for a string as well (referring to my use of ="Apples"), but cannot get it to run at all to test that part.
For a = 1 To ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
If TypeName(ActiveSheet.Cells(a, 1)) = "String" Then
If ActiveSheet.Cells(a, 1).Value = "Apples" Then
ActiveSheet.Rows(2).Insert
a = a + 1
ElseIf ActiveSheet.Cells(a, 1).Value = "Plums" Then 'One error here
ActiveSheet.Rows(4).Insert
a = a + 1
End If
End If
Next 'And here too
I'm trying to loop through listbox(attached picture below), and if the column(3) has value, then copy & paste row to empty row in excel sheet for later use.
I wanted to copy the row using column value to put it in sheet, but it just copys last row value, and repeats.
Could you please point out what I did wrong in the below code?
TIA
s = 22
For i = 0 To Me.AnBox.ListCount - 1
If Me.AnBox.Column(3) <> "" Then
Sheets("SparePartsRequestForm").Range("A" & s).Value = Me.AnBox.Column(2)
Sheets("SparePartsRequestForm").Range("C" & s).Value = Me.AnBox.Column(1)
Sheets("SparePartsRequestForm").Range("D" & s).Value = Me.AnBox.Column(3)
s = s + 1
End If
Next i
Userform
Part of excel sheet
Few errors:
The index of your ListBox.Column is zero based, so you not looking at the third but second Index.
You are accessing the values wrongly, trying to read a full column so it seems. The correct syntax is expression.Column(pvargColumn, pvargIndex) so you are missing a parameter. Check the documentation remarks to see the difference between using the second parameter or not.
Make use of the iteration and the more common List property to access each row individually.
So therefor your code could look like:
s = 22
For i = 0 To Me.AnBox.ListCount - 1
If Me.AnBox.List(i, 2) <> "" Then
Sheets("SparePartsRequestForm").Range("A" & s).Value = Me.AnBox.List(i, 1)
Sheets("SparePartsRequestForm").Range("C" & s).Value = Me.AnBox.List(i, 0)
Sheets("SparePartsRequestForm").Range("D" & s).Value = Me.AnBox.List(i, 2)
s = s + 1
End If
Next i
It is possible through the Column property too though:
s = 22
For i = 0 To Me.AnBox.ListCount - 1
If Me.AnBox.Column(2, i) <> "" Then
Sheets("SparePartsRequestForm").Range("A" & s).Value = Me.AnBox.Column(1, i)
Sheets("SparePartsRequestForm").Range("C" & s).Value = Me.AnBox.Column(0, i)
Sheets("SparePartsRequestForm").Range("D" & s).Value = Me.AnBox.Column(2, i)
s = s + 1
End If
Next i
Note: If your intention is to paste at the next available row, there are great ways to return the last used row of a range. See here for example
I am looking to compare the values in two columns that are located in different sheets. When a match is found I want to decrease the value in a third column that is in the same row as the matched values. I know how to hard code it below but I would rather not have to include this code for every row in excel.
If Range("g12").Value = Worksheets("Inventory Levels").Range("b2").Value Then
Worksheets("Inventory Levels").Range("c2").Value = Worksheets("Inventory Levels").Range("c2").Value - 1
End If
You can do this in a simple loop, see my comments for details.
Dim i as Integer
' Use "With" to fully qualify your sheet objects.
With ThisWorkbook
' Loop over rows 2 to 20 (change this as necessary)
For i = 2 to 20
' Use ampersand (&) for concatenation of strings
If .Sheets("Sheet1").Range("G" & (i + 10)).Value = .Sheets("Inventory Levels").Range("B" & i).Value Then
.Sheets("Inventory Levels").Range("C" & i).Value = .Sheets("Inventory Levelts").Range("C" & i).Value - 1
End If
Next i
End With
For innerLoop = 0 To addRowOffset = 1
Range("C" & countRow & ":" & "C" & (countRow + addRowOffset)).Value = _
ThisWorkbook.Sheets("Template").Range("B" & (4 + innerLoop)).Value
Next
So I have this code which is supposed to take some rows that I inserted into a sheet, and fill Colum "C" with the a range of strings from the "Template" sheet. However, all it does it put one string and copy over and over again into the cells. How, do I get this to put the entire range of strings into the other sheet?
I'm willing to provide more of the code, or information if needed.
You seem to be putting the same value from the Template worksheet into all of the Range("Cx") cells at once. You put different values in but you replace all of the Range("Cx") cells each time during the loop.
For innerLoop = 0 To addRowOffset
Range("C" & countRow + innerLoop).Value = _
Sheets("Template").Range("B" & (4 + innerLoop)).Value
Next innerLoop
That should put a different value into a different cell for each iteration of the loop.
Note the change in For innerLoop = 0 To addRowOffset as well.