Many online, including Microsoft's, help resources (for example) for functions that accept a vbCompareMethod state that there are 4 possible values:
vbUseCompareOption = -1 'Doesn't seem to exist
vbBinaryCompare = 0
vbTextCompare = 1
vbDatabaseCompare = 2
But I've just checked Access 2000, 2007 and 2016, and none of them seem to list vbUseCompareOption in the Object Browser as being present. If I have Option Explicit set, I get a compile error saying that vbUseCompareOption is an undefined variable.
Does that mean that any VBA that uses the constant vbUseCompareOption, without Option Explicit, is potentially getting unexpected results?
Is this a throwback to an earlier version of VBA, or perhaps an Access peculiarity, or just a widely distributed error in the help?
It seems you are right, in that vbUseCompareOption does not exisit as a member of enumeration vbCompareMethod
So, what happens when you try and use it? As you found, when using Option Explicit you get a compile error, because a variable of that name is not defined.
If you don't use Option Explicit (usually a bad idea), a variable is created at run time, of type Variant, and value Empty. I ran an experiment to see what happens:
TL:DR - yes, you may get unexpected results (Binary Compare is always used)
I created two modules, one with Option Compare Binary the other with Option Compare text. I used StrComp as a test function that uses a Compare parameter.
Module one
'Option Explicit
Option Compare Text
Sub DemoText()
Dim a As String, b As String
a = "AAA"
b = "aaa"
Debug.Print "Option Comapre Text"
Debug.Print "Text", "Binary", "Omitted", "vbUseCompareOption"
Debug.Print StrComp(a, b, vbTextCompare), StrComp(a, b, vbBinaryCompare), StrComp(a, b), StrComp(a, b, vbUseCompareOption)
End Sub
Module two
'Option Explicit
Option Compare Binary
Sub DemoBinary()
Dim a As String, b As String
a = "AAA"
b = "aaa"
Debug.Print "Option Comapre Binary"
Debug.Print "Text", "Binary", "Omitted", "vbUseCompareOption"
Debug.Print StrComp(a, b, vbTextCompare), StrComp(a, b, vbBinaryCompare), StrComp(a, b), StrComp(a, b, vbUseCompareOption)
End Sub
The test
Sub Demo()
DemoText
DemoBinary
End Sub
The Result
Option Comapre Text
Text Binary Omitted vbUseCompareOption
0 -1 0 -1
Option Comapre Binary
Text Binary Omitted vbUseCompareOption
0 -1 -1 -1
And if you assign a value of -1 to it, you get a run time error 5 "Invalid Procedure Call or argument"
So, vbUseCompareOption does not exist, creating it with a value of -1 (or just calling a function with Compare:=-1) as the help suggests, fails.
Letting VBA create it as a variable (with value Empty) has no effect. Binary compare is always applied.
AFAICT, the only way to use the Option Compare setting is to leave out the Compare parameter in a function call.
It's a very good question. I addressed it at the Access team.
That enum member seems to be a left-over from who-knows-where, has never been implemented, and will probably now be removed from the documentation - with some not so high priority.
So, to conclude, all mentions of vbUseCompareOption should simply be ignored.
Expanding on chris neilsen's post: If no Option Compare statement is specified:
Module Three
'Option Explicit
Sub DemoNoOptionCompare()
Dim a As String, b As String
a = "AAA"
b = "aaa"
Debug.Print "No 'Option Compare'"
Debug.Print "Text", "Binary", "Omitted", "vbUseCompareOption"
Debug.Print StrComp(a, b, vbTextCompare), StrComp(a, b, vbBinaryCompare), StrComp(a, b), StrComp(a, b, vbUseCompareOption)
End Sub
Sub Demo2()
DemoText
DemoBinary
DemoNoOptionCompare
End Sub
The Result
Option Compare Text
Text Binary Omitted vbUseCompareOption
0 -1 0 -1
Option Compare Binary
Text Binary Omitted vbUseCompareOption
0 -1 -1 -1
No 'Option Compare'
Text Binary Omitted vbUseCompareOption
0 -1 -1 -1
So the default when omitting the compare argument is controlled by the Option Compare statement if it exists, otherwise the default is a binary comparison.
Related
In MS Access I have a table with a Short Text field named txtPMTaskDesc in which some records contains numbers, and if they do, at different positions in the string. I would like to recover these numbers from the text string if possible for sorting purposes.
There are over 26000 records in the table, so I would rather handle it in a query over using VBA loops etc.
Sample Data
While the end goal is to recover the whole number, I was going to start with just identifying the position of the first numerical value in the string. I have tried a few things to no avail like:
InStr(1,[txtPMTaskDesc],"*[0-9]*")
Once I get that, I was going to use it as a part of a Mid() function to pull out it and the character next to it like below. (its a bit dodgy, but there is never more than a two-digit number in the text string)
IIf(InStr(1,[txtPMTaskDesc],"*[0-9]*")>0,Mid([txtPMTaskDesc],InStr(1,[txtPMTaskDesc],"*[0-9]*"),2)*1,0)
Any assistance appreciated.
If data is truly representative and number always preceded by "- No ", then expression in query can be like:
Val(Mid(txtPMTaskDesc, InStr(txtPMTaskDesc, "- No ") + 5))
If there is no match, a 0 will return, however, if field is null, the expression will error.
If string does not have consistent pattern (numbers always in same position or preceded by some distinct character combination that can be used to locate position), don't think can get what you want without VBA. Either loop through string or explore Regular Expressions aka RegEx. Set reference to Microsoft VBScript Regular Expressions x.x library.
Function GetNum(strS AS String)
Dim re As RegExp, Match As Object
Set re = New RegExp
re.Pattern = "[\d+]+"
Set Match = re.Execute(strS)
GetNum = Null
If Match.Count > 0 Then GetNum = Match(0)
End Function
Input of string "Fuel Injector - No 1 - R&I" returns 1.
Place function in a general module and call it from query.
SELECT table.*, GetNum(Nz(txtPMTaskDesc,"")) AS Num FROM table;
Function returns Null if there is no number match.
Well, does the number you want ALWAYS have a - No xxxx - format?
If yes, then you could have this global function in VBA like this:
Public Function GNUM(v As Variant) As Long
If IsNull(v) Then
GNUM = 0
Exit Function
End If
Dim vBuf As Variant
vBuf = Split(v, " - No ")
Dim strRes As String
If UBound(vBuf) > 0 Then
strRes = Split(vBuf(1), "-")(0)
GNUM = Trim(strRes)
Else
GNUM = 0
End If
End Function
Then your sql will be like this:
SELECT BLA, BLA, txtPMTaskDesc, GNUM([txtPMTaskDesc] AS TaskNum
FROM myTable
So you can create/have a public VBA function, and it can be used in the sql query.
It just a question if " - No -" is ALWAYS that format, then THEN the number follows this
So we have "space" "-" "space" "No" "space" "-" -- then the number and the " -"
How well this will work depends on how consistent this text is.
I'm trying to figure out a solution on how to concatenate strings from about 15 different options. Each result comes from a checkbox that is selected based on the state a person has lived in within a certain area.
I know how to turn the checkbox option into a text result. What I'm looking for is how to take these text results, combine them, then ignore null results so there isn't any weird spacing or formatting.
In short, if someone select 3 of the 15 results it would combine the 3 results cleanly and ignore the rest. Example would be: FL, CA, NY
There are, of course, multiple ways that this can be achieved, and since you didn't provide any code or examples of how you are attempting to do this, I will provide two options.
1 - You can concatenate the values using a combination of the & and + operators.
For example, let's say you have 15 checkboxes, all named similarly like chkState01, chkState02 ... through chkState15. And for the simplicity of my sample code, let's assume that when referencing the checkbox control directly in code as chkState01 that it will return either the 2 letter string abbreviation of the State it represents (i.e. NY) if the checkbox was checked, or it will return Null if the checkbox was not checked. With that, you could get your results in 2 ways:
Option A
StateList = (chkState01 + ",") & (chkState02 + ",") & (chkState03 + ",") ....
If those 3 check boxes returned the following values
chkState01 = "NY"
chkState02 = Null
chkState03 = "FL"
Then the result of that concatenation code would be:
NY,FL,
Notice that the string ends with an extra comma (,) and always would since you can't know ahead of time how many of the checkboxes will be checked. You would then need to trim that comma from your list before using it most likely.
Option B
'Create the list with a trailing comma that will need removed
Dim x as Integer
For x = 1 to 15
StateList = StateList & (Me("chkState" & Format(x, "00")) + ",")
Next x
or, you could do:
'Create the list without a trailing comma
Dim x as Integer
For x = 1 to 15
If Not IsNull(Me("chkState" & Format(x, "00"))) Then
If Len(StateList) > 0 Then
StateList = StateList & "," & Me("chkState" & Format(x, "00"))
Else
StateList = Me("chkState" & Format(x, "00"))
End If
End If
Next x
Notice that you can reference a control on a form by "generating" the name of that control as a string and referencing it in the Me("yourcontrolname") format. This is one advantage to naming controls that are similar in a fashion that lends itself to a looping structure like this. The Format command formats the number returned by x as a 2 digit with leading zeros i.e. 1 becomes 01
Further, using & to concatenate two items, where at least one of them is a string, will always result in a string output (Null & "S" = "S"). However, using the + to concatenate two items, where at least one of them is a Null, will always result in Null output (Null + "S" = Null). Hence the checkboxes where the value returns Null does not cause additional commas to be included in the result.
2 - You can write more complicated code to dynamically loop through the checkboxes and build the output list.
More likely, you are going to need to use additional code to determine which checkbox is which state abbreviation and to return the correct string value. Maybe you made the state abbreviation part of the checkbox name i.e. chkState_NY, chkState_FL or maybe you have put the abbreviation in the Tag property of each checkbox.
Let's say you used special control naming chkState_NY, chkState_FL. You could do the following:
Dim ctl as Access.Control
For Each ctl in Me.Controls
If ctl.Name Like "chkState_??" Then
If ctl.Value = True Then
If Len(StateList) > 0 Then
StateList = StateList & "," & Right(ctl.Name,2)
Else
StateList = Right(ctl.Name,2)
End If
End If
End If
Next ctl
It is possible to create User Defined Functions in MySQL just as we do in excel, if Yes How to do the same.
Also, If above is possible then how do i correlate (have same usage) the MySql Function with my existing excel function pasted below:
Public Function HexToText(Text As Range) As String
Dim i As Integer
Dim DummyStr As String
For i = 1 To Len(Text) Step 2
If Val("&H" & (Mid(Text, i, 2))) > 31 Then DummyStr = DummyStr &
Chr(Val("&H" & (Mid(Text, i, 2))))
DoEvents
Next i
HexToText = DummyStr
End Function
Please note that my Hex Data also contains Null (00) probable causing error while using Unhex
One example Values in Hex Column:
596f757220496e7465726e6574206163636f756e7420776974682044484c2042524f414442414e44204e4554205b505d204c494d4954454420686176696e6720757365726e616d652020414a57414454524156454c2077696c6c20657870697265206f6e20323031362d31302d30332032303a30303a313620506c656173652
Error Result Achieved via above UnHex command :
��W"��FW&�WB66�V�Bv�F�D��%$�D$�B�UB��ĔԕDTB�f��rW6W&��R�tEE$dT�v���W��&R��#b��2#��b�V6R
Actual Result should have been something like:
Your Internet account with DHL BROADBAND NET [P] LIMITED having username AJWDTRAVEL will expire on 2016-10-03 20:00:16
I have a query that compares a value. Both values are equal. Data types are double. However, the result is always false. Have you encountered the same scenario?
I tried to round off the data before comparing it and I got the correct results. What do you think is the cause of this issue?
This is a well known side effect of floating numbers.
You have several options. Test for a difference or convert to other data type:
Where Abs(Field1 - Field2) < 0.00001 (or whatever value you consider equal)
Where CCur(Field1) = CCur(Field2)
Where CDec(Field1) = CDecCur(Field2)
Confirm that the values are equal for both variables. Double is floating point with 15 decimal precision, I think. If your display is showing your double variables with rounding, they may appear equal but in fact they may not be equal.
I would recommend you to do Round(variable1, 4) and compare it with Round(variable2, 4). Try testing your variables with a test routine like this:
Public Sub SendDoubles()
Dim a As Double
Dim b As Double
a = 10.0000000001
b = 10.000000001
TestDoubles a, b
End Sub
Public Sub TestDoubles(a As Double, b As Double)
MsgBox CStr(a) & vbCrLf & CStr(b)
MsgBox a = b
MsgBox Round(a, 4) = Round(b, 4)
End Sub
Notice that CStr will convert your double to string so that you can visualize both variable's value. The 2nd MsgBox attempts to compare them as-is and the third one compares them with rounding.
How can I write NOT IN in TextBox expression?
I must check if some field value not belong to some list of strings, and then do some work.
Example:
Iif(SomeField.Value NOT IN ('Text1', 'Text2'), DoSomething, nothing)
I wrote code like this and got error when previewing report, and error was :
Overload resolution failed because no accessible 'Iif' accepts this number of type arguments
How can I do this stuff?
Try this small piece of custom code that accepts a string array. Just paste it into the report code section of the report..
Public Shared Function ValueExists(ByVal arr() as string, checkVal as string)
Dim i As Long
For i = LBound(arr) To UBound(arr)
If arr(i) = checkVal Then
return true
Exit Function
End If
Next i
return false
End Function
Usage would involve splitting the string into an array using the Split function
like so:
=iif(Code.ValueExists(Split("Your,comma,separated,string,in,here",","),"StringYouWantToFind")
,"Your value exists"
,"your value does not exist")
You can simply write the code like this:
Iif(SomeField.Value <> 'Text1' AND Field.Value <> 'Text2' , DoSomething, nothing)
I got this one in one report:
=iif(join(Parameters!Parameter1.Value,",") like "*" & Fields!Field1.Value & "*","Color1","Color2")
This instruction helps me to determine the fill colour of a cell inside a tablix, where:
Parameter1 is a multivalue parameter.
"Join" lets me have a string with all selected values from a multivalue parameter, eg. "value1,value2,value3,value4"
Field1 is the field that contains the values filtered by Parameter1
Color1 is the color if the value of the cell is included in the selection of parameter
else Color2
works well