In VBA, how to "if cbo.Column(0) = "certain value 1" Then - ms-access

(let's start by telling I'm a real beginner in coding)
I need to check for more than one value in a combox box column field, something like:
If me.cbo.Column(0) = "certain value 1" Then
If me.cbo.Column(0) = "certain value 2" Then
If me.cbo.Column(0) = "certain value 3" Then
Is there any syntax to have this on a single line of code ? or in the same expression ? like "certain value 1" or "certain value 2".
Or doesn't seems to work here.

As can't show properly in comments use the following syntax:
If me.cbo.Column(0) = "certain value 1" OR _
me.cbo.Column(0) = "certain value 2 " OR _
me.cbo.Column(0) = "certain value 3 " OR _ ' Extend as appropriate
me.cbo.Column(0) = "certain value n " Then
'Do something
End If
Line break _ allows you to extend whilst still being able to read the different OR conditions.

In general, you may choose to use a function, which tells you whether a value is in a given array of values. Like this:
Option Explicit
Public Sub TestMe()
Dim varArr As Variant
varArr = Array("test", "me", "today", "or")
Debug.Print valueInArray("test", varArr) 'true
Debug.Print valueInArray("test2", varArr) 'false
End Sub
Public Function valueInArray(myValue As Variant, _
myArray As Variant, Optional isString As Boolean = False) As Boolean
Dim counter As Long
If isString Then
myArray = Split(myArray, ":")
End If
For counter = LBound(myArray) To UBound(myArray)
myArray(counter) = CStr(myArray(counter))
Next counter
valueInArray = Not IsError(Application.Match(CStr(myValue), myArray, 0))
End Function
The function valueInArray tells you whether a value is present in an array. In your case, it can be used like this:
if valueInArray(me.cbo.Column(0), Array("certain value 1","certain value 2")) then

Related

Access 2016 How can I use the value of a variable not the variable?

Access 2016 VBA Code -
Lead in:
fullname is the table field name, tag is the property
msgbox fullname.tag
will show the value of tag
Problem:
Using the field name in a variable then trying to use the value of the variable
Example:
x = "fullname"
msgbox x.tag
does not show the contents of tag, error is: 424 object required
even if I Dim x as field or fields or variant I still can not get it to work.
How do I use the value of x, not x ?
Thank you in advance
You can't use a variable to reference a variable.
HOWEVER, you can most certainly use a string variable to referance a control on a form.
So,
dim strMyCtrl as string
strMyCtrl = "LastName"
Now,
msgbox "value of LastName = " & me!LastName
msgbox "Value of LastName = " & me("LastName")
msgbox "Value of LastName = " & me("LastName").Value
or
msgbox "Value of LastName = " & me(strMyCtrl)
msgbox "Value of LastName = " & me(strMyCtrl).Value
And since you can referance the control with a string, then you can also grab the tag value also
eg:
msgbox "Value of LastName control tag value = " & me(strMyCtrl).tag.
So, if you have controls 1 to 5 named:
TextBox1
TextBox2
TextBox3
TextBox4
TextBox5
You can grab the values like this:
dim i as integer
dim strCtrl as string
For i = 1 to 5
strCtrl = "TextBox" & i
msgbox "Value of " & strCtrl & " is = " & me(strCtrl)
Next i
So, no variable against a variable is allowed. However for controls, or even field names in a recordset, you can use a "string" variable with the name of the column, or as per above the name of the control.

Auto-Increment Letter to specific Number

I need help at Auto-Incrementing a letter.
A description field in Table1 has values like: B39
This Table1 Record, has related records in Table2:
B39_a
B39_b
B39_c
B39_d
All I want to do is that the description in Table2 automatically takes the record at table1 and adds the specific letter. It always starts with "a" and never reaches the full alphabet.
I already tried some code from this site: http://www.freevbcode.com/ShowCode.asp?ID=5440
Function IncrementString(ByVal strString As String) As String
'
' Increments a string counter
' e.g. "a" -> "b"
' "az" -> "ba"
' "zzz" -> "aaaa"
'
' strString is the string to increment, assumed to be lower-case alphabetic
' Return value is the incremented string
'
Dim lngLenString As Long
Dim strChar As String
Dim lngI As Long
lngLenString = Len(strString)
' Start at far right
For lngI = lngLenString To 0 Step -1
' If we reach the far left then add an A and exit
If lngI = 0 Then
strString = "a" & strString
Exit For
End If
' Consider next character
strChar = Mid(strString, lngI, 1)
If strChar = "z" Then
' If we find Z then increment this to A
' and increment the character after this (in next loop iteration)
strString = Left$(strString, lngI - 1) & "a" & Mid(strString, lngI + 1, lngLenString)
Else
' Increment this non-Z and exit
strString = Left$(strString, lngI - 1) & Chr(Asc(strChar) + 1) & Mid(strString, lngI + 1, lngLenString)
Exit For
End If
Next lngI
IncrementString = strString
Exit Function
End Function
Apparently it is not working like it should. It increases the letter, but twice! (i , i , j , j , etc.)
Description textbox (for Table2 Record ) has as default value:
=IncrementString(DLast("[SeqNo]","[table2]"))
But like I said it increases the number by doing it double. I also have to start the process manually by entering an "a".
Neither the function nor the calling code presently allows for the "A##_" prefix. If you really MUST save this prefix to Table2, code would have to be adjusted to deal with it. As is, suggest not saving the "A##" group identifier as a prefix in Table2. Use a query that joins tables on PK/FK fields to retrieve related data for export.
The DLast() search must account for the "A##" group identifier because the sequence is repeated for each group.
Unfortunately, trying to set a DefaultValue property with a dynamic parameter dependent on main form ID is impractical. For one thing, subform loads before main form so the default value cannot be built since the main form data and controls are not available. Also, when the main form is moved to a new record, again there is no data for the default value to build with. The result is error displays for the control on new record row.
Use PK/FK fields for the search.
Code in subform Current event to call your incrementing function:
If Me.NewRecord And Not IsNull(Me.Parent.ReferenzNR) Then
Me!SerienBezeichnung = IncrementString(Nz(DLast("SerienBezeichnung", "tbl_GrundminenSerie", "ID_FK=" & Me.Parent.ReferenzID), ""))
End If
Be aware that DLast(), even though working now, could eventually fail because records do not have inherent order. An alternative would likely involve a recordset or nested domain aggregate. Example tested in VBA Immediate Window:
?DMax("SerienBezeichnung","tbl_GrundminenSerie","ID_FK=5 AND Len([SerienBezeichnung])=" & DMax("Len([SerienBezeichnung])","tbl_GrundminenSerie","ID_FK=5"))
Or if you feel autonumber PK can be depended on to always be increasing (which has always been my observation although there is no guarantee with autonumber):
?DLookup("SerienBezeichnung","tbl_GrundminenSerie","ID_FK=5 AND SerienID=" & DMax("SerienID","tbl_GrundminenSerie","ID_FK=5"))
Consider the following VBA function:
Function IncAlpha(ByVal strA As String, ByVal lngI As Long) As String
If lngI <= 0 Then
IncAlpha = strA
ElseIf strA = vbNullString Then
IncAlpha = IncAlpha("a", lngI - 1)
Else
lngI = lngI + Asc(Right(strA, 1)) - 97
IncAlpha = IncAlpha(Left(strA, Len(strA) - 1), lngI \ 26) & Chr(97 + lngI Mod 26)
End If
End Function
Supplied with a lowercase alphabetical string, this recursive function will increment the string by the supplied long integer argument, with z incrementing to aa, az incrementing to ba and so on.
Supplied with an empty string (""), the above function will return a.
?IncAlpha("", 1)
a
?IncAlpha("", 26)
z
?IncAlpha("", 27)
aa
?IncAlpha("", 42)
ap
?IncAlpha("", 314159)
qvsa
With this function, the suffix may therefore be calculated using:
<prefix> & IncAlpha("", DCount("[SeqNo]","[table2]") + 1)
Or to account for multiple prefixes:
<prefix> & IncAlpha("", DCount("SeqNo","table2","SeqNo like '" & <prefix> & "*'") + 1)

Access: Compare array variable with string

I am trying to compare a value within an array with a text string.
The array is generated by splitting a record containing a string.
Please see the pseudo-code below.
Dim fish As Variant
fish = Split(myRS![Field2], " ")
If fish(Array reference hear?) = "whatever string" Then
'whatever else in hear
End If
I think I am having the following issues – referencing the correct part of the array and then converting the value to a string
If you need only to determine whether one or more of the array elements matches your search text, consider the Filter function.
In this example, Filter returns FishMatched as a one-dimensional array which contains the matching members from the first array (AllFish):
Dim AllFish As Variant
Dim FishMatched As Variant
AllFish = Split(myRS![Field2], " ")
FishMatched = Filter(AllFish, "whatever string")
If UBound(FishMatched) >= 0 Then
Debug.Print UBound(FishMatched) + 1; " match(es) found."
Else
Debug.Print "No match found."
End If
This approach may be suitable if you only need to know whether your search text is present among the members of AllFish. However, since it creates a new array containing the matches, it can not tell you the index of the AllFish member which matched.
You need a for loop to cycle the strings inside your array. LBound and UBound are needed to get the range of your array. You can check inside the loop if theStringYouAreLookingFor Is equal to the value of current array position i
Dim fish As Variant
Dim theStringYouAreLookingFor as String
theStringYouAreLookingFor = "here is what I'm looking for"
fish = Split(myRS![Field2], " ")
For i = LBound(fish) To UBound(fish)
If theStringYouAreLookingFor = fish(i) then
Debug.Print "Found it at " & cstr(i + 1) & " position in array"
Exit for
End If
Next i

Select Case Is < 0 true on negative numbers

What started as a simple validation code converted in something very paradoxical in my eyes.
The following code returns "Good work!" when I input a negative number in the InputBox popup
Dim myvar As String
myvar = InputBox("input a positive number, please")
If IsNumeric(myvar) Then
myvar = CDbl(myvar)
Select Case myvar
Case Is < 0
MsgBox "I need a positive number"
Exit Sub
Case Is > 0
MsgBox "Good work!"
[MyField] = myvar
RunCommand acCmdSaveRecord
Me.Requery
Exit Sub
Case Else
MsgBox "You entered '" & myvars & "'. I don't know what to do about"
End Select
Else
MsgBox "A Number, please"
End If
Is this really the best way to validate an InputBox?
Since myvar is a String, CDbl(myvar) will get implicitly converted back to a string. Create a temporary numeric variable for the Select Case.
I agree with some of the other answers. Think about this code re-write (notice the second variable declared):
Dim myvar as String
Dim myDbl as Double
myvar = inputBox ("Input a positive number, please")
if isnumeric(myvar) then
myDbl = cDbl(myvar)
else
msgbox "Enter a number please"
exit sub
end if
if mydbl <=0 then
msgbox "I need a positive number"
else 'if mydbl > 0 then
MsgBox "Good work!"
[MyField] = myvar
RunCommand acCmdSaveRecord
Me.Requery
end if
That would solve you problems by accounting for zero and declaring a separate variable as a double there. The if statement instead of the case is just preference I suppose. But now think about the two variables you have.
debug.print "MyVar is a string containing: " & myvar
debug.print cstr(cdbl(myvar)*2)
'This forces myvar into a double(a number-type) to do math on it and then print it out
However, if you were to re-run the first print, you would see that myvar is still a string and can be used like a string. In VBA, unlike some other languages, variables are only what you declare them as. If you want to use them as other things, you have to declare another variable of the needed type.
TL;DR Think of them as different containers. Strings are circle boxes and doubles are square boxes. They might be able to hold similar stuff but the functionality of the containers is limited by their shape. In VBA you don't have a way to force a circle into a square so you have to make a whole second container and transfer the stuff over.

Proper way to check if an unbound control has a value

Simple scenario: a form and one text box (unbound), Text1.
If "" <> Text1 Then
MsgBox "Not Empty"
End If
The above code works. The expression ""<> Text1 evaluates to True if the text box contain characters.
The opposite doesn't work, regardless of the text box is empty or not:
If "" = Text1 Then ' or alternatively, False = ("" <> Text1)
MsgBox "Empty!"
End If
Can you clarify this issue?
The textbox is usually null if it does not contain anything, this is not the same as a zero length string (""). It can often be best to use:
If Trim(Text1 & "") = vbNullString
'Empty
This will be true if the textbox contains spaces, a zero length string or null.
Alternatively, I've got a small function that I find useful for checking that sort of thing when dealing with various variable types and I just want to know whether it's blank.
'-----------------------------------------------------------------------------'
' True if the argument is Nothing, Null, Empty, Missing or an empty string. '
'-----------------------------------------------------------------------------'
Public Function IsBlank(arg As Variant) As Boolean
Select Case VarType(arg)
Case vbEmpty
IsBlank = True
Case vbNull
IsBlank = True
Case vbString
IsBlank = (arg = vbNullString)
Case vbObject
IsBlank = (arg Is Nothing)
Case Else
IsBlank = IsMissing(arg)
End Select
End Function
Just Made a blog post today about it too.
I always use the function Nz (variable, valueIfNull) to check those kind of things. For example:
if (Len(Nz(Me.txt1, "")) > 0) then
'Me.txt1 does not contain a value
end if
Or if I want to save a textbox's value to a recordset:
rst!Name = Nz(Me.txtName, "No name given")