Integrate Replace in a Private Sub - vba

How to integrate Replace in this Private Sub?
I need to replace all words "NONE" with "":
Private Sub UpdateSKU()
Dim str As String
str = Me.Combo216.Column(1) & Space(1) & Me.Combo224.Column(1) & Space(1)
Me.Text423.Value = str
End Sub
I have tried
Private Function NONE(a As String)
If InStr(a, "NONE") > 0 Then
MsgBox "Original: " & a & vbCrLf & "Adjusted: " & Replace(a, "NONE", "")
End If
End Function
But I can't get it to work.

A function should return a value...
Your function does not declare a return type, nor does it ever assign a return value.
Try this instead:
Private Function NONE(a As String) As String
NONE = Replace(a, "NONE", "")
End Function

Try this:
Private Sub UpdateSKU()
Dim Text As String
Text = Me.Combo216.Column(1) & Space(1) & Me.Combo224.Column(1) & Space(1)
Me.Text423.Value = Replace(Text, "NONE", "")
End Sub
Also, don't use common function names (Str) for variables, and do rename your controls to something meaningful.

Related

How to use this VBA code to use as Public Subroutine in Access VBA

I have got this code below that restricts users to leave an empty field in a form. Now I want to use this in all of my forms. I've tried to use in Public Subroutine using a module. But it doesn't work.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim msg As String, Style As Integer, Title As String
Dim nl As String, ctl As Control
nl = vbNewLine & vbNewLine
For Each ctl In Me.Controls
If ctl.ControlType = acTextBox Then
If ctl.Tag = "*" And Trim(ctl & "") = "" Then
msg = "Data Required for '" & ctl.Name & "' field!" & nl & _
"You can't save this record until this data is provided!" & nl & _
"Enter the data and try again . . . "
Style = vbCritical + vbOKOnly
Title = "Required Data..."
MsgBox msg, Style, Title
ctl.SetFocus
Cancel = True
Exit For
End If
End If
Next
End Sub
I just want to use this in all of my forms. How do I accomplish this?
Good question, and good idea.
So, keep in mind that "me" is just the current form you are working with.
So, create a plane jane standard code module. And drop in your function like this with a "few" changes.
Public Function CheckRequired(MyMe As Form) As Boolean
Dim msg As String
Dim Style As Integer
Dim Title As String
Dim nl As String
Dim ctl As Control
nl = vbCrLf ' crlf gives you one line
CheckRequired = False ' assume everything ok
For Each ctl In MyMe.Controls
If ctl.ControlType = acTextBox Then
If ctl.Tag = "*" And Trim(ctl & "") = "" Then
msg = "Data Required for '" & ctl.Name & "' field!" & nl & _
"You can't save this record until this data is provided!" & nl & _
"Enter the data and try again . . . "
Style = vbCritical + vbOKOnly
Title = "Required Data..."
MsgBox msg, Style, Title
ctl.SetFocus
CheckRequired = True
Exit Function
End If
End If
Next
End Function
Now, in the forms event (which has that cancel), then you do this:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Cancel = CheckRequired(Me)
End Sub
As #June7 mentioned, Me is only valid behind forms and reports. It is shorthand alias for the form/report name/object. To achieve what you are looking for, you can try this concept. Create the global routine like below :
Public Function Validate_BeforeUpdate(frm As Form) As Integer
Dim msg As String, Style As Integer, Title As String
Dim nl As String, ctl As Control
nl = vbNewLine & vbNewLine
For Each ctl In frm.Controls
'''' your other code
Validate_BeforeUpdate = 1
Exit For
Next
End Sub
And to use this from your other forms, do it like below :
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Validate_BeforeUpdate(Me) = 1 Then
Cancel = True
End If
End Sub
This is not a tested code, if you follow this idea, you should be okay to have what you are trying to do.

Save reports according to choice from a sub form

I have a main form called (frmcarSearch) that displays table data called (tblCar).
The form contains three drop-down menu (cmbCar, cmbType, cmbGroup) that allow user to filter data and display them in a sub-form called (frmCarSub)
and there are three buttons to save the filtered data btnPrint, btnPDF, btnExcel.
The question is: How to write a code for each button so that the report displays (or save) the data in the sub-form according to the choice from each drop-down menu?
The code for each combo box:
Private Sub cmbCar_AfterUpdate()
Me.cmbGroup.Value = ""
Me.cmbType.Value = ""
Me.frmCarSub.SetFocus
Me.frmCarSub.Form.Filter = "[CarNum]= '" & [cmbCar] & "'"
Me.frmCarSub.Form.FilterOn = True
End Sub
Private Sub cmbType_AfterUpdate()
Me.cmbGroup.Value = ""
Me.cmbCar.Value = ""
Me.frmCarSub.SetFocus
Me.frmCarSub.Form.Filter = "[TypeName]='" & [cmbType] & "'"
Me.frmCarSub.Form.FilterOn = True
End Sub
Private Sub cmbGroup_AfterUpdate()
Me.cmbCar.Value = ""
Me.cmbType.Value = ""
Me.frmCarSub.SetFocus
Me.frmCarSub.Form.Filter = "[CarGroupName]= '" & [cmbGroup] & "'"
Me.frmCarSub.Form.FilterOn = True
End Sub
I used this code for btnPrint button
Private Sub btnPrint_Click()
If IsNull([cmbCar]) Then
DoCmd.OpenReport "rptCar", acViewPreview
Else
DoCmd.OpenReport "rptCar", acViewPreview, , "[CarNum]='" & [cmbCar] & "'"
End If
End Sub
But the problem with this code is that I have to use three buttons for the three menus and this is illogical.
Thank you.
You could define a function such as the following with the module for your form:
Function FilterString() As String
If Not IsNull(cmbCar) Then FilterString = " AND [CarNum]= '" & cmbCar & "'"
If Not IsNull(cmbType) Then FilterString = FilterString & " AND [TypeName]= '" & cmbType & "'"
If Not IsNull(cmbGroup) Then FilterString = FilterString & " AND [CarGroupName]= '" & cmbGroup & "'"
FilterString = Mid(FilterString, 6)
End Function
Then, define another function such as:
Function SetFilter()
Me.frmCarSub.SetFocus
Me.frmCarSub.Form.Filter = FilterString
Me.frmCarSub.Form.FilterOn = True
End Function
Then, the event handlers for each of your comboboxes become:
Private Sub cmbCar_AfterUpdate()
SetFilter
End Sub
Private Sub cmbType_AfterUpdate()
SetFilter
End Sub
Private Sub cmbGroup_AfterUpdate()
SetFilter
End Sub
Finally, the Print button event handler can become:
Private Sub btnPrint_Click()
If FilterString = vbNullString Then
DoCmd.OpenReport "rptCar", acViewPreview
Else
DoCmd.OpenReport "rptCar", acViewPreview, , FilterString
End If
End Sub
And the user also has the ability to filter by more than one field.

Name depends on the number of characters

How to write a conditional statement acting as follows:
If "% name%" has 1 character, name: 00 "% name%"
If "% name%" has 2, name: 0 "% name%"
If "% name%" has 3 , name: "% name%"
action.SetDynamicParameter("FileName", ((((((("%version%" + "_") _
+ String.Join(", ", array2)) _
+ "_") _
+ "%name%") _
+ ".jpg"))
I will be grateful for your help.
It looks to me like your just trying to pad a number as a string with leading zeros to a length of 3. Is that correct? If so, try this:
Private Function FormatMyName(ByVal Name As String) As String
Return Name.PadLeft(3, "0")
End Function
If created it as a function so it's easier for you to add the additional formatting you need (e.g. adding a .jpg extension)
Check the return of the Function for Nothing or check the length of the string before passing it to the Function.
Private Function GetPaddedName(OriginalName As String) As String
Dim PaddedString As String = ""
Select Case OriginalName.Length
Case 1
PaddedString = "00" & OriginalName & ".jpg"
Case 2
PaddedString = "0" & OriginalName & ".jpg"
Case 3
PaddedString = OriginalName & ".jpg"
Case Else
PaddedString = Nothing
End Select
Return PaddedString
End Function

Find a line by searching for a string, then edit a line which is 2 lines below

My first question here, I'll try to be as clear as possible.
I have a text file that looks like this :
[...]
"tickets"
{
"436" "320000000400000083421a060100100104"
"674" "320000000400000083421a06010010010a"
"292" "320000000400000083421a0601001001f0"
"551" "320000000400000083421a0601001001da"
}
"99550"
{
"informations" "254"
"parameters" "-banana -lemon"
}
"99551"
{
"informations" "641"
"parameters" "-banana -lemon"
}
"550"
{
"informations" "551"
"parameters" "-banana -lemon"
}
"551"
{
"informations" "123"
"parameters" "-banana -lemon"
}
"552"
{
"informations" "987"
"parameters" "-banana -lemon"
}
[...]
What I want to do is:
search for this string in the text file :
"551"
{
add -apple to the parameters line which is 2 lines below, should look like this :
"parameters" "-banana -lemon -apple"
I think it's the only way to find this line, but I don't get the coding skills to get it done.
You can try something like this:
Function ReplaceSpecial(ByVal text As String, ByVal find As String, ByVal insert As String) As String
Dim allLines() As String = Split(text, vbCrLf)
Dim lineNumber = Array.IndexOf(allLines, find)
Dim lineToUpdate = Array.FindIndex(Of String)(allLines, lineNumber, Function(f) f.Trim.StartsWith("""parameters"""))
allLines(lineToUpdate) = allLines(lineToUpdate).Trim.Substring(0, allLines(lineToUpdate).Length - 1) & " " & insert & """"
Return Join(allLines, vbCrLf)
End Function
Sample Usage:
Assuming that your input text is in a textbox named InputTextBox the following code will show you updated text in OutputTextBox.
OutputTextBox.Text = ReplaceSpecial(InputTextBox.text, """550""", "-apple")
Here's another one, not much different than Pradeep Kumar's submission:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FileName As String = "C:\Users\Mike\Documents\SomeFile.txt"
Dim lines As New List(Of String)(File.ReadAllLines(FileName))
AddParameterToSection(lines, "551", "-apple")
AddParameterToSection(lines, "552", "-orange")
File.WriteAllLines(FileName, lines)
End Sub
Private Sub AddParameterToSection(ByVal lines As List(Of String), ByVal sectionID As String, ByVal parameter As String)
Static DoubleQuote As String = Chr(34)
Static Parameters As String = DoubleQuote & "parameters" & DoubleQuote
Static PairOfDoubleQoutes As String = DoubleQuote & DoubleQuote
Dim header As String = DoubleQuote & sectionID & DoubleQuote
Dim index As Integer = lines.FindIndex(Function(x) x.Trim() = header)
If index <> -1 Then
Dim endBracket As Integer = lines.FindIndex(index, Function(x) x.Trim() = "}")
Dim paramIndex As Integer = lines.FindIndex(index, Function(x) x.Trim().StartsWith(Parameters))
If paramIndex <> -1 AndAlso paramIndex < endBracket Then
If lines(paramIndex).EndsWith(PairOfDoubleQoutes) Then
lines(paramIndex) = lines(paramIndex).Replace(PairOfDoubleQoutes, DoubleQuote & parameter & DoubleQuote)
Else
lines(paramIndex) = lines(paramIndex).TrimEnd(DoubleQuote) & " " & parameter & DoubleQuote
End If
End If
End If
End Sub

VB.Net Regex Help

I've got 3 or 4 patterns that I'm comparing user input against and I need to figure out if the user input matches one of the patters and to return the match if it does.
Since the input is multiline, I'm passing each individual line like so:
Dim strRawInput() As String = Split(txtInput.Text, vbCrLf)
Dim strInput As String
txtOutput.Text = ""
For Each strInput In strRawInput
strInput.Trim(vbCr, vbLf, Chr(32))
Validation(strInput)
Next
Then I have this to find matches:
Dim m As Match
For i = 0 To strValidator.Length - 1
Dim r As New Regex(strValidator(i))
m = r.Match(strInput)
If m.Success Then
txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
Exit Sub
Else
End If
Next
txtOutput.Text = txtOutput.Text & "Not this time" & vbCrLf
How can I do this more efficiently? Also, I added the Exit Sub there to avoid showing the "Not this time" message even after a match is found (if the match is with one of the later patterns in the array), but I'd like to find a better way of doing that too.
Thanks in advance.
Rather than generating your Regexs in the loop, generate them one time at the startup of the application. So maybe something like:
Private Shared m_regexes As New List(Of Regex)
Shared Sub New()
For Each v As String In strValidator
m_regexes.Add(New Regex(v))
Next
End Sub
And then you can change your other code to:
For Each r As Regex In m_regexes
Dim m As Match = r.Match(strInput)
If m.Success Then
txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
Exit Sub
Else
End If
Next
Regarding the Exit Sub, I think it's fine, You've discovered that it matches at least one pattern, so why continue to evaluate the rest. But if you don't like methods that can "return" in multiple places, you could just replace it with a Boolean and a Exit For as:
Dim found as Boolean = false
For Each ...
If IsMatch Then
found = True
Exit For
End If
Next
If Found Then
....
Else
.....
End If
Hmm if that's the case then wouldn't this be even better?
For i = 0 To strValidator.Length - 1
Dim r As New Regex(strValidator(i))
Dim m As Match = r.Match(strInput)
If m.Success Then
txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
Exit Sub
End If
Next