I have a spreadsheet where the user can define some rules, but I'm struggling with getting the log to work. I want difference results based on what the user wants, but ideally I want to stay away from have to but multiple select cases in or if lines.
What I have Is this (Simplified - It's in a loop so the values will change for every row - I'm just using an example):
The operator can vary, it could be ">","=>" etc.
Field1Value = "Football"
Operator1 = "="
Rule1 = "Football"
If Evaluate(Field1Value & Operator1 & Rule1 ) Then
'Run My Code
End If
So in the above example the logic would be true and my code would run, but I'm getting a type mismatch error.
Has anyone any ideas?
Thanks
Chris
********UPDATE********
Here's the full Code:
Workbooks(MasterWB).Activate
Sheets("Rules").Select
NoRules = Sheets("Rules").Range("J6").End(xlDown).Row
For a = 7 To NoRules
Field1 = Workbooks(DataWB).Sheets(DataWS).Rows(1).Find(Workbooks(MasterWB).Sheets("Rules").Cells(a, 10), , xlValues, xlWhole).Column
Operator1 = Sheets("Rules").Cells(a, 11)
Rule1 = Sheets("Rules").Cells(a, 12)
Operator = Sheets("Rules").Range("J5").Cells(a, 13)
Field2 = Workbooks(DataWB).Sheets(DataWS).Rows(1).Find(Workbooks(MasterWB).Sheets("Rules").Cells(a, 14), , xlValues, xlWhole).Column
Operator2 = Sheets("Rules").Cells(a, 15)
Rule2 = Sheets("Rules").Cells(a, 16)
HighlightColumn = Workbooks(DataWB).Sheets(DataWS).Rows(1).Find(Workbooks(MasterWB).Sheets("Rules").Cells(a, 17), , xlValues, xlWhole).Column
HighlightColour = Workbooks(MasterWB).Sheets("Rules").Cells(a, 17).Interior.ColorIndex
Workbooks(DataWB).Activate
With Workbooks(DataWB).Sheets(DataWS)
.Select
Lastrow = .UsedRange.Rows.Count
For b = 2 To Lastrow
Field1Value = .Cells(b, Field1).Value
If Evaluate(Field1Value & Operator1 & Rule1) Then
.Cells(b, HighlightColumn).Interior.ColorIndex = HighlightColour
End If
Next b
End With
Next a
Assuming that you're expecting "Football" = "Football" yields True, then give this a try:
If Evaluate("""" & Field1Value & """ " & Operator1 & " """ & Rule1 & """") Then
Note, I enclosed my strings in quotes - you need to pass those to Evaluate()
Actually, according to my reading of the MS Docs, I don't think this will work.
Evaluate(Name)
Name: A formula or the name of the object, using the naming convention of Microsoft Excel. The length of the name must be less than or equal to 255 characters.
What is the definition of "Football"? Is it a simple text string? My reading indicates that Evaluate() will execute a built in function or a UDF, but not a simple comparison.
Hold on I don't mean to steal Credit from FreeMan but following worked for me:
Sub test()
Dim Field1Value As String
Dim Operator1 As String
Dim Rule1 As String
Dim test As Range
Dim Passed As Boolean
Field1Value = "Football"
Operator1 = "="
Rule1 = "Football"
Passed = Evaluate("=" & """" & Field1Value & """" & Operator1 & """" & Rule1 & """")
'Different way of achievieng same thing ignore this if you want to
Set test = Range("A1")
test.Formula = "=" & """" & Field1Value & """" & Operator1 & """" & Rule1 & """"
Passed = test.Value
MsgBox Passed
End Sub
I tried it a with several values and operator and it works fine.
So I would only correct FreeMan by adding "=" & as first part of Evaluate.
So to make this more concise I'm saying write this :
Evaluate("=" & """" & Field1Value & """" & Operator1 & """" & Rule1 & """")
Try something like below:
Field1Value = "Football"
Operator1 = "="
Rule1 = "Football"
Dim x As Variant
strEvaluate = Chr(34) & Field1Value & Chr(34) & Operator1 & Chr(34) & Rule1 & Chr(34)
x = Evaluate("IF(" & strEvaluate & ",1,0)")
if x = 1 then
'Run your code
end if
Or instead of 1 and 0 use TRUE and FALSE. My language is not English. But I think this works also.
x = Evaluate("IF(" & strEvaluate & "," & True & ", " & False & ")")
if x = TRUE then
'Run your code
end if
Related
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)
I want to divide a long query here is part of it, when I remove the second line (indicated with !!) everything is ok but when I add, receive error "type mismatch". The reason is the lenght of line cause if I shorten second line and add there is no problem.
This method I use to divide query but receive error cause of line lenght any idea ?
strSqla = "SELECT DT4 .ABH, DT4 .S1 , CASE WHEN S1 = 'AV' OR S1 = 'AN' OR S1 = 'AY' THEN 'PDE' "
' !!!!!!strSqla = strSqla & "WHEN S1 = 'AE' OR S1 = 'AH' OR S1 = 'AK' OR S1 = 'FE' THEN 'EME' "
strSqla = strSqla & "ELSE 'MANUAL' END AS division "
strSqla = strSqla & "FROM H9.PCFILES.DT4 DT4 WHERE DT4 .IDATE > '" & X & "'"
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:="ODBC;DSN=PCFILES289;", Destination:=Range("$A$1")).QueryTable
.CommandText = Array(strSqla)
.RowNumbers = False
use line continuators and string concatenation:
strSqla = "SELECT DT4 .ABH, DT4 .S1 , CASE WHEN S1 = 'AV' OR " & _
"S1 = 'AN' OR S1 = 'AY' THEN 'PDE' WHEN S1 = 'AE' OR " & _
"S1 = 'AH' OR S1 = 'AK' OR S1 = 'FE' THEN 'EME' " & _
"ELSE 'MANUAL' END AS division FROM H9.PCFILES.DT4 " & _
"DT4 WHERE DT4 .IDATE > '" & X & "'"
As an addition to what Macro Man said:
there's a limit to line continuation at about 20 lines
after that one has to resort to something like you did
strSqla = " .... "
strSqla = strSqla & " .... "
either way, the query construction gets clumsy rather quick, especially if you have single quote 'string-expressions'
So, should you use longer SQLs frequently and change them occassionally, consider one of the following Alternatives:
A) Storing the SQL in separate textfiles, then read them into a string with a stored function like so:
Function fetchSQL(path As String) As String
Dim Line As String
Dim iFile As Integer
iFile = FreeFile
Open path For Input As #iFile
Do Until EOF(iFile)
Line Input #iFile, Line
fetchSQL = fetchSQL & vbNewLine & Line
Loop
Close #iFile
End Function
and use it in your code like this:
strSqla = fetchSQL("c:\yourpath\p01.sql")
B) Alternatively, if you prefer storing your SQL inside your workbook (assuming you use excel), you ofc store the SQL inside a worksheet-column instead and use something like this:
Function fetchSQL as String()
Dim i as Integer
i = 1
While Not IsEmpty(yoursheet.Cells(i, 2))
fetchSQL = strSQL & vbCrLf & " " & yoursheet.Cells(i, 2).Value
i = i + 1
Wend
End Function
It worked , for getting sql query from a cell this is the correct codes ;
Function fetchSQL() As String
Dim i As Integer
i = 1
While Not IsEmpty(Sheets("sheet2").Cells(i, 7))
fetchSQL = fetchSQL & Sheets("Sheet2").Cells(i, 7).Value & " "
i = i + 1
Wend
End Function
Tried second option but still get error type mismatch here are images
I am having an issue trimming white space characters. When I enter a value and give spaces before and after the value in Excel, I see spaces surrounding it but I should not see those extra spaces.
I would like to remove these spaces but I'm not sure how to achieve this, here is the output that I'm getting currently:
ServerName = " testing "
but the generated output should be like this...
ServerName = "testing"
Here is the code that I'm using in my project:
If Sheets(Itm).Cells(i, 2) = "Required1" Then
MsgBox "Enter the value for required field : " & Sheets(Itm).Cells(i, 1)
Return
End If
Value = Replace(Sheets(Itm).Cells(i, 4).Value, vbLf, " ")
'Value = Sheets(Itm).Cells(i, 4).Value
Try this (Untested)
Value = Trim(Sheets(Itm).Cells(i, 4).Value)
Value = Application.WorksheetFunction.Clean(Value)
Print #1, Sheets(Itm).Cells(i, 1) & "=" & Value
Here is a sample code to understand how it works...
Sub sample()
Dim sample As String
sample = "Sid"
Debug.Print Len(sample) '<~~ This will give you 3
sample = " " & vbNewLine & sample & vbNewLine & vbCrLf & vbLf
Debug.Print Len(sample) '<~~ This will give you 11
sample = Trim(sample)
Debug.Print Len(sample) '<~~ This will give you 10
sample = Application.WorksheetFunction.Clean(sample)
Debug.Print Len(sample) '<~~ This will give you 3
End Sub
Replace:
Print #1, Sheets(Itm).Cells(i, 1) & "=" & Value
With:
Print #1, Replace(Sheets(Itm).Cells(i, 1) & "=" & Value," ","")
I'll try to make this as short as possible.
I need to rewrite the formulas of a number of cells depending on what worksheet they're located in.
Dim sFrmla As String
Dim rSomerange As Range
Let sFrmla = "=OFFSET(INDIRECT(INDIRECT(" & Chr(34) & "E" & Chr(34) & "&ROW()));0;"
Let rSomerange.Formula = sFrmla & wsSheet.Name & "_ZERO_SCALE)"
Let rSomerange.Formula = sFrmla & wsSheet.Name & "_FULL_SCALE)"
Let rSomerange.Formula = sFrmla & wsSheet.Name & "_PRCSUNIT)"
This crashes at the second line (Zero_scale) and gives me a runtime error 1004. I have already made sure that the range itself exists and is writable.
Funny part is that the same code but without the formula string works just fine.
Let rSomerange.Formula = wsSheet.Name & "_ZERO_SCALE)"
Any ideas?
there is no need to use Let keyword. It's odd in this case.
no matter what is the default separator for your regional
settings (comma , or semicolon ;), you should always use comma
, with Range.Formula. If you'd like to use your regional
separator (semicolon ; in your case), use Range.FormulaLocal
instead.
So, you should use:
sFrmla = "=OFFSET(INDIRECT(INDIRECT(" & Chr(34) & "E" & Chr(34) & "&ROW())),0,"
rSomerange.Formula = sFrmla & wsSheet.Name & "_ZERO_SCALE)"
or
sFrmla = "=OFFSET(INDIRECT(INDIRECT(" & Chr(34) & "E" & Chr(34) & "&ROW()));0;"
rSomerange.FormulaLocal = sFrmla & wsSheet.Name & "_ZERO_SCALE)"
or shorter version:
sFrmla = "=OFFSET(INDIRECT(INDIRECT(""E""&ROW())),0,"
My goal is to return the results of 5 textboxes into a SQL query, by incorporating the Query string with the variables.
How can I get my code to function so that when a checkbox is checked, the value (eg: ID, SC...) is recorded and placed into a Query? And if a checkbox is not checked, then it is not placed into the query.
The 5 checkboxes are as follows:
The code I current have to record whether a textbox is selected, and to place the value (eg: ID, SC, AS...) into a variable is as follows:
If (Me.BoxID = False) And (Me.BoxSC = False) And (Me.BoxASSC = False) And (Me.BoxAS = False) And (Me.BoxEH = False) Then
MsgBox "You must check a Fonction Checkbox", 0
Exit Sub
Else
If (Me.BoxID= True) Then IDValue = Chr(34) & "ID" & Chr(34) Else IDValue = """"""
If (Me.BoxSC= True) Then SCValue = Chr(34) & "SC" & Chr(34) Else SCValue = """"""
If (Me.BoxASSC= True) Then ASSCValue = Chr(34) & "ASSC" & Chr(34) Else ASSCValue = """"""
If (Me.BoxAS= True) Then ASValue = Chr(34) & "AS" & Chr(34) Else ASValue = """"""
If (Me.BoxEH= True) Then EHValue = Chr(34) & "EH" & Chr(34) Else EHValue = """"""
End If
fonctionQryString = "(((tblF.f1)=" & IDValue & ") OR " + "((tblF.f1)=" & SCValue & ") OR " + "((tblF.f1)=" & ASSCValue & ") OR " + "(tblF.f1)=" & ASValue & ") OR " + "(tblF.f1)=" & EHValue & ")))"
The fonctionQryString goes into the WHERE section of the SQL Query.
I know that the method I'm using is not efficient, even though it works.
My problem is that I don't know how to do this another way. I want my code to function so that when a checkbox is not checked, it doesn't go into the Query string.
Any help would be much appreciated.
These two WHERE clauses should produce equivalent results. Consider switching to the second form.
WHERE tblF.f1 = "ID" OR tblF.f1 = "SC" OR tblF.f1 = "AS"
WHERE tblF.f1 IN ("ID","SC","AS")
Here is a rough and untested code sample to produce a similar WHERE clause based on my understanding of what you're trying to achieve.
Dim fonctionQryString As String
Dim lngLoopNum As Long
Dim strControlName As String
Dim strValueList As String
For lngLoopNum = 1 To 5
Select Case lngLoopNum
Case 1
strControlName = "ID"
Case 2
strControlName = "SC"
Case 3
strControlName = "ASSC"
Case 4
strControlName = "AS"
Case 5
strControlName = "EH"
End Select
If Me.Controls("Box" & strControlName) = True Then
strValueList = strValueList & "," & Chr(34) & _
strControlName & Chr(34)
End If
Next
If Len(strValueList) > 0 Then
fonctionQryString = "tblF.f1 IN (" & Mid(strValueList, 2) & ")"
Else
MsgBox "You must check a Fonction Checkbox"
End If
I assumed you didn't actually want to include the condition, WHERE tblF.f1 = "" (an empty string). If I guessed wrong, you'll have more work to do, but hopefully this will still point you to something useful.