How can I use the COUNTIF() function to count only certain text strings that exist in the range?
I tried to use the below, but I get an error of
Syntax error
This is the syntax I attempted
Dim worksheetmaster As String = "Master"
Dim worksheettocheck As String = "New"
Dim softcount As Int, i As Long, hardcount As Int
softcount = Evaluate("=COUNTIF(Range('" & worksheettocheck & "'!A:A'" & worksheetmaster & "'!A" & i & ")"Soft")")
hardcount = Evaluate("=COUNTIF(Range('" & worksheettocheck & "'!A:A'" & worksheetmaster & "'!A" & i & ")"Hard")")
EDIT
I tried to use this syntax without the Range and am still getting the error
hardcount = Evaluate("=COUNTIF('" & worksheettocheck & "'!A:A'" & worksheetmaster & "'!A" & i & ")"Hard"")
To match in column A with Hard in column B, this is how it should be:
hardcount = Application.Evaluate("COUNTIFS('" & worksheettocheck & "'!A:A,'" & worksheetmaster & "'!A" & i & ",'" & worksheettocheck & "'!B:B, ""Hard"")")
softcount = Application.Evaluate("COUNTIFS('" & worksheettocheck & "'!A:A,'" & worksheetmaster & "'!A" & i & ",'" & worksheettocheck & "'!B:B, ""Soft"")")
Your first syntax errors are here:
Dim worksheetmaster As String = "Master"
Dim worksheettocheck As String = "New"
You can't do that. Instead, you would need to use:
Dim worksheetmaster As String
Dim worksheettocheck As String
worksheetmaster = "Master"
worksheettocheck = "New"
Even better would be to assign them to point diectly at the worksheets, but let's work with your code as much as possible instead of totally rewriting it.
For the countif, you cannot join ranges that way. You haven't even assigned a value to i, but assuming i = 1, your code:
softcount = Evaluate("=COUNTIF(Range('" & worksheettocheck & "'!A:A'" & worksheetmaster & "'!A" & i & ")"Soft")")
evaluates to total nonsense in VBA:
softcount = Evaluate(=COUNTIF(Range('New'!A:A'Master'!A1)Soft))
Now, from what I can tell, what you are trying to do is to count how many times the value in cell Master!A & i appears in the range New!A:A, depending whether Master!A & i="Soft" or Master!A & i="Hard". So let's see if we can find code that will do that.
For data we enter "Soft" into Master!A1 and "Hard" into Master!A2. Then we enter random "Soft" or "Hard" into various cells in the column New!A:A.
Now your code looks like this:
Dim worksheetmaster As String
Dim worksheettocheck As String
Dim softcount As Long, i As Long, hardcount As Long
worksheetmaster = "Master"
worksheettocheck = "New"
i = 1
softcount = Application.CountIf(Sheets(worksheettocheck).Range("A:A"), Sheets(worksheetmaster).Range("A" & i).Value)
i = 2
hardcount = Application.CountIf(Sheets(worksheettocheck).Range("A:A"), Sheets(worksheetmaster).Range("A" & i).Value)
This is inefficient and limited, but it retains as much of your original code as possible, and it works.
Edited to add: if "Hard" is in Master!B & i instead of A & i then the code becomes:
i = 1
softcount = Application.CountIf(Sheets(worksheettocheck).Range("A:A"), Sheets(worksheetmaster).Range("A" & i).Value)
hardcount = Application.CountIf(Sheets(worksheettocheck).Range("A:A"), Sheets(worksheetmaster).Range("B" & i).Value)
Related
I have the goal to write a formula in a set of rows. Some references in the formula have to change each row.
I implemented the following script:
Dim i As Integer
Dim formcolM As String
Dim temprng As String
For i = 0 To 100
formcolM = "NUMBERVALUE(IF(Q" & i & "=""Bedarf kum."";A" & i & ";IF(Q" & i & "=""Ist"";OFFSET(A" & i & ";-1;0);IF(Q" & i & "=""Lz."";OFFSET(A" & i & ";-2;0);IF(Q" & i & "=""Ist+Lz.-Bedarf"";OFFSET(A" & i & ";-3;0);)))))"
Let temprng = "M" & i
Range(temprng).Select
ActiveCell.Value = "\=" & formcolM
next i
With this script I am writing a string each row in my excel table at column M.
I noticed that if the formula hasn't the symbol "\" , you can find an error .
In order to avoid the error I thought to leave the symbol "\" and to use a trick deleting it after (because I don't know how to solve with R1C1 formula. I read some answers on Stackoverflow, but unfortunately I did not understand )
The replacing script after the for cycle:
Columns("M:M").Replace What:="\=", Replacement:="=", LookAt:=xlPart
The strange thing is that the macro doesn't delete it.
Infact when the script finishes , it seems that nothing happened, without errors. But if I want substitute "\=" with another symbol, for example "*", the replacing script works.
I did not understand if the problem is :
the replace method did not recognized the symbol "=" to search
I cannot use the replace method because the symbol "=" disturbs in some way , I don't know in what.
OR, is there another simplest way to get this task done?
Someone could help me in order to fix? I should have the formula working in the column M , automatically with vba (not with another formula in the excel sheet) .
Thanks in advance for your time.
We can apply the formula directly. The issue is that vba is very US-EN Centric and all formula when using the .Formula needs to be in that format.
Also since your formula refers to values in a row 3 above the one in which it is put we need to start the loop at 4 not 0. There is no row 0
There are two ways, in US-En format with English functions and , as the deliminator using .Formula:
Dim i As Integer
For i = 4 To 100
Range("M" & i).Formula = "=NUMBERVALUE(IF(Q" & i & "=""Bedarf kum."",A" & i & ",IF(Q" & i & "=""Ist"",OFFSET(A" & i & ",-1,0),IF(Q" & i & "=""Lz."",OFFSET(A" & i & ",-2,0),IF(Q" & i & "=""Ist+Lz.-Bedarf"",OFFSET(A" & i & ",-3,0),)))))"
Next i
Or using .FormulaLocal and the formula as you would write it in your native tongue.
Dim i As Integer
For i = 4 To 100
Range("M" & i).FormulaLocal = "=NUMERO.VALORE(SE(Q" & i & "=""Bedarf kum."";A" & i & ";SE(Q" & i & "=""Ist"";SCARTO(A" & i & ";-1;0);SE(Q" & i & "=""Lz."";SCARTO(A" & i & ";-2;0);SE(Q" & i & "=""Ist+Lz.-Bedarf"";SCARTO(A" & i & ";-3;0);)))))"
Next i
By the time I got this worked out, Scott already had an answer. I just wanted to post your original code modified to work. I would suggest his method.
Sub TestScript()
Dim i As Integer
Dim formcolM As String
Dim temprng As String
For i = 4 To 100
formcolM = "NUMBERVALUE(IF(Q" & i & "=" & "Bedarf kum." & ";A" & i & ";IF(Q" & i & "=" & "Ist" & ";OFFSET(A" & i & ";-1;0);IF(Q" & i & "=" & "Lz." & ";OFFSET(A" & i & ";-2;0);IF(Q" & i & "=" & "Ist+Lz.-Bedarf" & ";OFFSET(A" & i & ";-3;0);)))))"
temprng = "M" & i
Sheets("Sheet1").Range(temprng).Select
ActiveCell.Value = " = " & formcolM
Next i
End Sub
I have written the code below so that it will retreive the file locations and put them into Path Column(B) which corresponds to the .csv column(C) where a "YES" is found.
Dim csv_ap As Range
Dim path_report2 As String
Sheets("Mail Report").Activate
Set csv_ap = Range("C65000").End(xlUp)
If csv_ap.Value = "YES" Then
path_report2 = MAIN_PATH & "1. Invoices+BUFs - " & Sheets("Sheet1").Range("D65000").End(xlUp).Value _
& "\" & Sheets("Sheet1").Range("C65000").End(xlUp).Value & " - " & Sheets("Sheet1").Range("AK65000").End(xlUp).Value _
& "\" & "LOGGED" & "\" & Sheets("Sheet1").Range("E65000").End(xlUp).Value
csv_ap.Offset(0, -1) = path_report2
End If
As you can see only the bottom row for column B has been filled. I'm not 100% sure why this is but could be down to not having a loop involved? I have tirelessly looked into adding a loop but cannot do so without affecting the current code. Any ideas?
I have edited the code above and got a loop working. But now it is duplicating the bottom row.
Dim cell As Range
Dim path_report2 As String
Sheets("Mail Report").Activate
For Each cell In Sheets("Mail Report").Range("C2:C10").Cells
If cell = "YES" Then
path_report2 = MAIN_PATH & "1. Invoices+BUFs - " & Sheets("Sheet1").Range("D65000").End(xlUp).Value & "\" & Sheets("Sheet1").Range("C65000").End(xlUp).Value & " - " & Sheets("Sheet1").Range("AK65000").End(xlUp).Value & "\" & "LOGGED" & "\" & Sheets("Sheet1").Range("E65000").End(xlUp).Value
cell.Offset(0, -1) = path_report2
End If
Next
This is the result of the macro:
Your range is defined as a single cell by Set csv_ap = Range("C65000").End(xlUp).
If you want to process all the rows from 1 to the last occupied range, then you would need:
Set csv_ap = Range("C1:C" & Range("C65000").End(xlUp).Row)
So I'm trying to do a couple things with this subroutine but can't get VBA to execute the .FormulaArray function.
Create a named range using offset & lastrow function
Use cell references to insert into the array formula
--
Sub namedrange()
Dim firstrow As Long
Dim LastRow As Long
Dim ColToLetter, absolute, Title, mc, mc1
ActiveCell.Offset(0, -1).Select
absolute = ActiveCell.Address
LastRow = ActiveSheet.Cells(Rows.Count, ActiveCell.Column).End(xlUp).Row
firstrow = ActiveCell.Row
ColLetter = Mid(ActiveCell.Address, 2, 1)
ActiveSheet.Range(ColLetter & firstrow & ":" & ColLetter & LastRow).Name = Range(ColLetter & "1").Value
Title = Range(ColLetter & "1").Value
ActiveCell.Offset(0, 1).Select
mc = ActiveCell.Offset(-1, 0).Address
mc = Mid(mc, 2, 3)
mc1 = Replace(mc, "$", "")
ActiveCell.FormulaArray= "=IF(ROWS(mc & "":"" & mc1)>SUM(IF(FREQUENCY(IF(Title<>"""",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),1)),"""",INDEX(Title,SMALL(IF(FREQUENCY(IF(Title<>"""",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),ROW(Title)-ROW(absolute)+1),ROWS(mc & "":"" & mc1))))"
End Sub
The formula bar shows what the vba function is outputting, which is not what I want. I don't know why it won't output the references I've created like mc should be "$A$2" not "mc".
Also when I try to execute the FormulaArray code I get a runtime error 1004 "Unable to set the FormulaArray property of the Range class"
Your .FormulaArray content has some typos. Here's how it should look like (assuming all the above code is fine):
ActiveCell.FormulaArray= "=IF(ROWS(" & mc & ":" & mc1 & ")>SUM(IF(FREQUENCY(IF(Title<>" & chr(34) & chr(34) & ",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),1))," & chr(34) & chr(34) & ",INDEX(Title,SMALL(IF(FREQUENCY(IF(Title<>" & chr(34) & chr(34) & ",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),ROW(Title)-ROW(absolute)+1),ROWS(" & mc & ":" & mc1 & "))))"
In general, remember that if you want the value of a variable to be printed into a string, you cannot write "a=mc+3" but rather a = " & mc & "+3".
I am really stuck on this. I have used numeric string formatting before, but not out of a datagridview. Any time I try to format a number to "0.000" string from the datagridview it does nothing, just returns the number in the cell unformatted. Can anyone help correct this?
For Each manualprocess In ManualAddOperationsdgv.Rows
If manualprocess.cells(2).value.ToString = "DRILL" Then
If lasttool <> manualprocess.cells(4).value.ToString Or lastoffset <> manualprocessoffset Or lastdepth <> manualprocess.cells(10).value Then
If Not lasttool = 0 Then
builder.AppendLine("M9M5M1")
End If
builder.AppendLine("")
builder.AppendLine("N" & blocknumber & "(" & manualprocess.cells(1).value.ToString & " - DRILL OPERATION)")
blocknumber += 1
builder.AppendLine("G65P7000T" & manualprocess.cells(4).value.ToString & "M6B#.S" & manualprocess.cells(12).value.ToString & "CC#." & manualprocessoffset & "(D#)")
builder.AppendLine("G66P7015E" & manualprocess.cells(3).value.ToString & "R.1Q" & manualprocess.cells(14).value.ToString & "Z-" & manualprocess.cells(10).value.ToString("0.0000") & "S" & manualprocess.cells(12).value.ToString & "F" & manualprocess.cells(13).value.ToString("0.0000") & manualprocessoffset)
End If
builder.AppendLine("X" & manualprocess.cells(8).value.ToString("0.000") & "Y" & manualprocess.cells(9).value.ToString("0.000"))
End If
Next
The ToString function doesn't know what type of object is in your cell, so try converting your value into a decimal or a double first:
Dim decValue As Decimal
If Decimal.TryParse(manualprocess.Cells(8).Value.ToString, decValue) Then
builder.AppendLine("X" & decValue.ToString("0.000") ...
End If
I have a list of dynamic length from columns A to F. (starts at row 1) I need to make a code to have this list printed on a pop up. I don not want it printed on another sheet, the sheet this list is on is very hidden. I need to minimize copying these numbers thus why i don't want it on another sheet.
The proble is as i said this list is of dynamis length. So I'd have something like:
msgbox(upf.cells(1,1) & " " & upf.cells(1,2) & " " & upf.cells(1,3) & " " & upf.cells(1,4) _
upf.cells(2,1) & " " & upf.cells(2,2) & " " & upf.cells(2,3) & " " & upf.cells(2,4) _
... up to row lr)
How can I write this in some sort of a for i= 1 to lr loop?
Thank you!
As a basic example...
Sub tgr()
Dim upf As Range
Dim cIndex As Long
Dim rIndex As Long
Dim sMsg As String
Set upf = Range("A1", Cells(Rows.Count, "F").End(xlUp))
For rIndex = 1 To upf.Rows.Count
For cIndex = 1 To upf.Columns.Count
sMsg = sMsg & " " & upf.Cells(rIndex, cIndex)
Next cIndex
Next rIndex
MsgBox Mid(sMsg, 2)
End Sub