I'm trying to write a function in my Microsoft access application to return a blank string when a "-" or "null" is inputted, and when any other string is inputted it should return the original string.
This is what I have so far:
Public Function cleanOutput(inStr As String)
If inStr = "-" Or inStr = "null" Then
cleanOutput = ""
Else
cleanOutput = inStr
End If
End Function
However this is not working. I'm sure this is a very basic solution, however I have zero experience with VB programming, so I'm not sure what I'm doing wrong here. Any help is greatly appreciated!!
Not quite sure what "not working" means, but if "null" means a true Null, you can use:
Public Function cleanOutput(inStr As Variant) As String
If Nz(inStr, "-") <> "-" Then
cleanOutput = inStr
End If
End Function
I changed the variable name from inStr to something else and everything worked as expected!
Related
I'm trying to remove any parenthesis or value enclosed in parenthesis in a string field in SSRS, which will be the best way to do it? I read about replace function but not sure how to use it with several values.
Here are some examples about what I'm trying to do:
Original string Expected string
ERP(123) ERP
TE(PO)ST TEST
(123)string string
Assuming you only have a single set of parentheses then this will work.
=LEFT(Fields!test.Value, InStr(Fields!test.Value, "(") -1)
&
MID(Fields!test.Value, InStr(Fields!test.Value, ")") +1)
Basically we take the left part of the string up to the first "(" position minus 1
and then concatenate the remainder of the string starting at the first ") +1
For this I would use a function that would be usable everywhere and not always copy paste:
In here we do a Substring of the part we want to delete, and then we do a Replace to changed with no spaces and that way the string will be together (in the case if the original was separated by the parenthesis)
Public Function removeParenthesis (input As Object) As Object
Try
Dim FirstIndex As Integer = input.IndexOf("(")
Dim SecondIndex As Integer = input.IndexOf(")") - FirstIndex + 1
Dim Result As String = input.ToString().Replace(input.Substring(FirstIndex, SecondIndex), "")
Return Result
Catch ex As Exception
Return ex
End Try
End Function
This is pasted in the Code sections and will be called like this:
Code.removeParenthesis(Fields!Textbox1.Value)
The function is implemented on Report > Report Properties > Code > paste the function above
EDIT
Taking in mind what #Alan Schofield said in his answer
Assuming you only have a single set of parentheses [...].
I have made a little change and have validate too if there's actually some parenthesis, the idea is to loop till everything is clean.
If there's no parenthesis then It'll return original value
Public Function removeParenthesis(input As Object) As Object
Try
Dim Result As String = input.ToString()
Dim FirstIndex As Integer = Result.IndexOf("(")
Dim SecondIndex As Integer = Result.IndexOf(")")
While FirstIndex <> -1 And SecondIndex <> -1
SecondIndex = SecondIndex - FirstIndex + 1
Result = Result.Replace(Result.Substring(FirstIndex, SecondIndex), "")
FirstIndex = Result.IndexOf("(")
SecondIndex = Result.IndexOf(")")
End While
Return Result
Catch ex As Exception
Return ex
End Try
End Function
I have a table with values
Errors:
X_11;SR_4;D_11;SR_2
SR_4;T_22
E_18; E_28; SR_3;
E_28; SR_3;
SR_2;SR_4
I need to put in a query to parse the values so that anything with SR comes up so I do like "*SR*" but in the output I need to display only this:
Errors:
SR_4;SR_2
SR_4
SR_3
SR_3
SR_2;SR_4
I would like this in query with many fields other than this one ... instead of VBA. I am using MS Access 2010, I am guessing some type of parsing with each field being separated with ";" that will only capture SR ones?
I think regular expressions might be a way to go.
In VBA, you need to enable the reference to "Microsoft VBScript Regular Expressions 5.5". This question and its accepted answer has a detailed descrpition on what are Regular Expressions and how to enable them in your project (it's for Excel, but for Access is the same route).
Once you have the reference enabled, this little function will give you a "clean" string:
Public Function filterString(str As String)
Dim re As RegExp, obj As Object, x As Variant, first As Boolean
Set re = New RegExp
With re
.Global = True
.IgnoreCase = True
.MultiLine = False
.Pattern = "SR_[0-9]" ' This will match the string "SR_"
' followed by a digit
End With
filterString = ""
first = True
If re.Test(str) Then
Set obj = re.Execute(str)
For Each x In obj
If first Then
first = False
Else
filterString = filterString & ";"
End If
filterString = filterString & x
Next x
End If
End Function
If you test it you'll see that the result is:
filterString("X_11;SR_4;D_11;SR_2")
SR_4;SR_2
which is the result you want.
Now, a simple select query will give you what you need:
select filterString([Errors]) as err
from [yourTable]
where [yourTable].[Errors] like '*sr*'
Hope this helps
I think you can get what you need by splitting your input string into an array and then using the Filter function to create a second array which includes only the SR_ matches from the first array. Finally Join the second array to produce your output string which contains the matches.
Public Function filterString(ByVal pInput As String) As String
Dim array1() As String
Dim array2() As String
array1 = Split(Replace(pInput, " ", vbNullString), ";")
array2 = Filter(array1, "SR_")
filterString = Join(array2, ";")
End Function
Compared to a regular expression approach, this function is more concise. I find the logic simpler. And it does not require setting a reference.
Notice also it will accommodate SR codes which include more than a single digit (in case that eventually becomes a requirement). For example:
? filterString("X_11;SR_4;D_11;SR_234")
SR_4;SR_234
You could use that function in a query in the same way #Barranka suggested:
SELECT filterString(y.Errors) AS sr_codes
FROM [yourTable] AS y
WHERE y.Errors Like '*sr*';
I know there's several posts which are similar to the one I am posting, and I've looked through them and still can't figure out what I am doing wrong. I've also checked out how to properly set up a CASE statement using VBA, but still can't find what I am doing wrong.
Basically, I have a user-entry form where the user enters a part number which looks something like this: 0 A1B2-3C-4D-5E6F. Once the user has added the record, the part number should scan the string for any " " or "-" and replace them with "", to look like this: A1B23C4D5E6F, and update the record in the table.
Here is the code I am using: (txtString as my field)
Public Function strReplace(txtString As Variant) As Variant
Select Case txtString
Case "-"
strReplace = ""
Case " "
strReplace = ""
Case Else
strReplace = txtString
End Select
End Function
I am still learning the ropes with VBA, but this compiles fine. Did I structure this code wrong, logically, for what I am trying to accomplish, or have I set up my code wrong? I appreciate all feedback and answers.
Thanks
EDIT This code is being called when frmAddString opens(within access' Macros & Code - Visual Basic - Form_frmAddString)
EDIT2 I am trying this in a testing database which has the following:
tblTestingStrings
-Field1: StringID
-Field2: txtString
frmAddString(My code is located on this Pop up form which opens in Add)
-btnSaveandClose
-txtString
-StringID
EDIT3 Code for frmAddString
Option Compare Database
Private Sub btnSaveandClose_Click()
DoCmd.Save
DoCmd.Close
End Sub
Public Function strReplace(txtString As String) As String
Select Case txtString
Case "-"
strReplace = ""
Case " "
strReplace = ""
Case Else
txtString = strReplace
End Select
End Function
txtString being the place where the user types in a word.
It's actually easer that what you're doing.
Public Function strReplace(txtString As Variant) As Variant
strReplace = Replace(Replace(txtString, " ", ""), "-", "")
End Function
im trying to check if a number is a text or number in a banking system. If the value is incorrect it should erase and send an error message, but my code isnt working at all... can someone help me? here is the code:
Private Sub TextBox1_Change()
name = TextBox1
If Application.IsText(name) = True Then
IsText = True
Else
MsgBox "Insert only words"
Selection.name.Delete
End If
End Sub
I think you should be using name = TextBox1.Text instead. It's probably giving you an error on that line.
Also, you may want to wait until the user is finished typing the response, I believe the changed event will run each time a character is pressed. The AfterUpdate will run after you tab or click away from the textbox.
And really, instead of deleting the response (which I don't think will work), you should simply set the textbox blank back to an empty string.
Private Sub TextBox1_AfterUpdate()
If Not MyIsANumber(TextBox1.Text) Then
MsgBox ("It's Text")
Else
TextBox1.Text = ""
End If
End Sub
Function MyIsANumber(str As String) As Boolean
For i = 1 To Len(str)
If IsNumeric(Mid(str, i, 1)) Then
MyIsANumber = True
Exit Function
End If
Next
MyIsANumber = False
End Function
I'm sure the code could be structured better, but there's something along the lines of what you need. In this case, it just wipes the textbox if there is a number entered. Obviously, things will need to be the opposite for your textbox that you want to contain a number.
Have you considered the vartype() function? https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/vartype-function
I'm writing a function that requires input and my data validation looks very awkward. If InputFld isn't "A","B", or "C", then it's an error:
If InputFld <>"A" and InputFld<>"B" and InputFld<>"C" then goto ErrorHandler
This just looks ugly to me. Is there a more elegant solution? I'd like to just write something like:
If InputFld not in ("A","B","C") then goto ErrorHandler
See? Much easier to read and maintain this way. But I don't know how to do it.
How about:
If Instr("ABC",InputFld)=0 Then
At least two ways to do that:
public function IsInSet(byval value as variant, paramarray theset() as variant) as boolean
dim i as long
for i=lbound(theset) to ubound(theset)
if value = theset(i) then
isinset = true
exit function
end if
next
end function
Usage: If not IsInSet(val, "A", "B", "C") then ...
public function IsInSet(byval value as variant, theset as variant) as boolean
dim i as long
for i=lbound(theset) to ubound(theset)
if value = theset(i) then
isinset = true
exit function
end if
next
end function
Usage: If not IsInSet(val, array("A", "B", "C")) then ...
Eval() should allow you to do something similar. This expression returns -1 (True):
Debug.Print Eval("""g"" Not In (""a"",""b"",""c"")")
I wouldn't call that elegant, though.
Consider using the Like operator. This expression returns True:
Debug.Print Not "g" Like "[abc]"