Counting cells using Excel VBA which are a result of a vlookup statement - vba

I have a spreadsheet on one sheet with the values in column C being generated using the results of a vlookup statement, from a value which I enter in column A.
I need to be able to count the number of cells in column C up to a maximum of 51 rows (from row 1 to row 51) which have a value in them, not including errors, after I have entered all my values in column A.
Oh - by the way, each time I do the count there will be a different number of rows used.
I've tried using:
ccc = Range("C:C").Cells.SpecialCells(xlCellTypeConstants).Count
but this only counts the first line which is my header row.
Sorry if there is already an answer out there, but I've been looking for quite a while and can't find anything.
Thanks.

You can easily do this without VBA, but you could try:
sub testy()
dim myRange as range
dim numRows as long
Set myRange = Range("C:C")
numRows = Application.WorksheetFunction.CountA(myRange) - _
myRange.SpecialCells(xlCellTypeFormulas, xlErrors).Count
end sub
Your code is not working because xlCellTypeConstants is specifically telling it to count only constant values, ignoring formulas calculated values.

The worksheet function CountA counts only cells with values:
=CountA(C1:C51)
We can call any worksheet function from VBA with the WorksheetFunction function:
dim c as integer
c = WorksheetFunction.CountA([C1:C51])
CountIf can be used to skip errors:
Skip errors with: `=COUNTIF(D5:D9,">0")`

You are looking to count cells that have no errors.
Replace your vlookup by the below formula. So all errors will be replaced by "NOT FOUND" Text
=IFERROR(VLOOKUP(C1,A1:B3,2,FALSE), "NOT FOUND")
Then add this to find the number of cells that are non blank and non erroneous
=COUNTA(D:D) - COUNTIF(D:D,"NOT FOUND")
Assumptions:-
A:B Source Range
C Lookup Column
D the vlookup function is in this coulmn
For VBA
cnt = Application.WorksheetFunction.CountA(D:D) - Application.WorksheetFunction.Countif(D:D, "NOT FOUND")

Related

Macro to hardcode rows subject to a value in column A of each row

I am new to VBA and I am stuck!
I am trying to write a macro that will search through column A of my worksheet, and then if it finds a "1" then it will hardcode that row.
I have the below which I found online and adapted, but it only works where column A contains hardcoded values of 1 or 0. In reality my column A is a formula the output of which is 1 or 0.
Is there a simple way to fix the below so that the code can react to a formula output of 1 rather than just a hardcoded input of 1?
Sub formulatovalue()
ActiveSheet.Select
Dim c As Range
For Each c In Columns(1).SpecialCells(xlConstants)
If c.Value = "1" Then
c.EntireRow.Value = c.EntireRow.Value
End If
Next c
End Sub

Count values that aren't blank or N/A - VBA

I had figured out this formula to count all those values that weren't blank, but the system updated the template and now besides blank it has also "N/A" values.
How can I transform this
=COUNTIF('R Plan'!XT2:XT3658,"<>")
To test if besides NOT blank also test for NOT N/A
Because I tried this
=COUNTIF('R Plan'!XT2:XT3658,"<>" OR "<>N/A")
and I'm getting a message that we found an error on your formula
If you're using >=XL2007 then you can use COUNTIFS:
=COUNTIFS('R Plan'!XT2:XT3658,"<>",'R Plan'!XT2:XT3658,"<>N/A")
If you're using <=XL2003 then you can use:
=SUM(COUNTIF('R Plan'!XT2:XT3658,"<>"),-COUNTIF('R Plan'!XT2:XT3658,"N/A"))
Count the number that are not empty and minus those that have N/A.
or
=SUMPRODUCT(('R Plan'!XT2:XT3658<>"")*('R Plan'!XT2:XT3658<>"N/A"))
If you want to use VBA, then this will work for you,
Put this in a cell and choose your range =COUNTBLANKS(B1,A1:A21) , B1 being the value you want to count and the second range is the range you want to count how many times that value occurs.
Add a module and paste this function in it.
Function COUNTBLANKS(r As Range, rng As Range) As Long
Dim x
Dim c
x = rng
For Each c In x
If c = r Then
COUNTBLANKS = COUNTBLANKS + 1
End If
Next c
End Function

Using loop and sum functions with Vlookup

I've got a macro that essentially searches column C in Sheet1 for the value "Rec" and copies the corresponding value in column D, then pastes it into the last open cell in column B of Sheet2. It does just what it is supposed to do and is as follows:
Sub FindPasteGSVInNextCell()
Worksheets("Sheet2").Activate
Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value = _
WorksheetFunction.VLookup("Rec", Sheet1.Range("C2:H25"), 2, False)
End Sub
I now want the code, instead of just searching for a single "Rec" value, to search for all rows with "Rec" in column C and to sum up all of their corresponding values in column D, then place that sum into Sheet2.
I am assuming that I need some kind of Do Until loop or something, but I am not exactly sure how to format it... I am a beginner with VBA, so any help would be greatly appreciated.
vlookup will not work as it will continue to only grab the first instance of "Rec".
On Sheet 2 list all the possible categories in column A then in column B1 put
= sumif(Sheet1!C:C,A1,Sheet1!D:D)
then copy down. This will Get you the totals by category.
If you want to use VBA, you will still need a list of categories setup somewhere, either hard coded or listed somewhere that you can loop through.
If your list was in column A on Sheet2 then you would:
dim ws as worksheet
set ws = Worksheets("Sheet2")
For each i in ws.range(ws.Range("A1"),ws.Range("A1").offset(xldown)).Cells
i.offset(,1) = WorksheetFunction.Sumif(Worksheets("Sheets1").Range("C:C"), _
i,Worksheets("Sheets1").Range("D:D"))
next i

Best way to return data from multiple columns into one row?

I have a sheet with just order numbers and another with order numbers and all of the data associated with those order numbers. I want to match the order numbers and transfer all of the available data into the other sheet. I've been trying to use loops and VLOOKUP but I'm having problems (plus I have 116 columns I want to transfer data from so my vlookup expression doesn't look very nice). Any advice would be appreciated!
this is what I have so far and I'm getting an object error.
I don't think it's the right way to go about it in general though.
Dim LookUpRange As Range
Dim row As Range
Set LookUpRange = Worksheets("batches").Range("B4:B1384")
Set row = Worksheets("batches").Range("C:DL")
For Each row In LookUpRange
row.Select
Selection.FormulaArray ="=VLOOKUP(RC[-1],OrderLvl!RC[-1]:R[1380]C[113],{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,207,108,109,110,111,112,113,114,115},FALSE)"
Next row
End Sub
Please consider this VBA script to resolve your inquiry:
Sub LookupOuput()
Dim OrderNumberColumn As Range
Set OrderNumberColumn = Worksheets("batches").Range("B2:B1384")
Dim LookUpRange As Range
Set LookUpRange = Worksheets("OrderLvl").Range("C:DL")
Dim cell As Range
Dim FindResult As Range
For Each cell In OrderNumberColumn
If Not cell.Value2 = Empty Then
Set FindResult = LookUpRange.Find(what:=cell.Value2)
If Not FindResult Is Nothing Then
cell.Range("A1:DJ1").Value2 = LookUpRange.Rows(FindResult.row).Value2
End If
End If
Next cell
End Sub
Basically searches for each Order Number in the first sheet on the second sheet. This outputs (if search term exists) the cell that that string is found which we later refer to its row number to output the whole row to the first sheet. Cheers,
A regular VLOOKUP may be able to give you what you need, if you use a small trick...
Insert a row above the data table, and put sequential numbers in
each cell of that row. (ie, A1 = 1, B1 = 2, C1 = 3, etc...)
Do the same thing on your blank table.
Assuming that your first order number is in cell A2, put the following formula into B2: =VLOOKUP($A2,[other sheet name]!$A$1:$DZ$5000,B$1,0)
Drag this formula across all 116 columns, then down all however many rows you've got.
You'll need to adjust the ranges, obviously, but make sure that your lookup array starts in column A. (or alternatively, that your numbers start in the same column as the first column in your array.) Adding the numbers along the top allows you to change what column of the array you're referencing, just by dragging the cell formula.

Is there a VBA method equivalent to the SQL SELECT query?

With an Excel Worksheet, I'm trying to search rows that matches some criteria in their cells value.
I need something like the SQL SELECT query to proceed search through Excel Worksheet, is there such method in VBA? A method that returns a Range of rows that matches the search criteria.
I have tried with the Range AutoFilter method but I can not use the returned object as a Range to access cells in the returned rows.
I'm really new to Excel VBA so sorry if my question looks strange or stupid
You can use the Union() function to create a range. Here's an simplified example (say you wanted to select the entire rows in which the value in the A column was an even number and highlight them yellow):
Sub UnionTest()
Dim myRange As Range
Dim cell As Range
For Each cell In Range("A1:A100")
If cell Mod 2 = 0 Then
If myRange Is Nothing Then
Set myRange = cell
Else
Set myRange = Union(myRange, cell)
End If
End If
Next
myRange.EntireRow.Interior.Color = vbYellow
End Sub
Please note that you need to check if the range is empty or not before you use union on it (and color it but to make the code easier to read I have omitted it here), thus the If-Then statement. Depending on what you want to do to each row, it might be more effecient to just do the process on the row during the for-each loop.
Hava a look at these funcitons
VLOOKUP
HLOOKUP - same as VLookup but for rows
LOOKUP()
INDEX() and MATCH()
OFFSET() and MATCH()
How to find data in an Excel table
How to Use VLOOKUP or HLOOKUP to find an exact match
Hope these help