"FISH" will always be in "SHELLFISH" but what if a string has both FISH and SHELLFISH in it? - Nicelabel 5.0 [duplicate] - vbscript

This question already has an answer here:
splitting string and putting each output into a unique variable in vbs
(1 answer)
Closed 5 months ago.
I am very new to programming and I am writing some code to work with Nicelabel 5.0 to display small pictures of allergens on a product label when the allergen is present within a string. I thought I really nailed it by using inStr to see if certain strings were present. I was even able to make the program distinguish between "FISH" and "SHELLFISH"
if inStr (1, Allergens1, "FISH") > 0 then
if inStr (1, Allergens1, "SHELLFISH") > 0 then
a = label.SetObjectVisible("SHELLFISH", true)
else
a = label.SetObjectVisible("FISH", true)
end if
end if
Where I'm stuck is what do I do if a product has BOTH shellfish and fish in it? The string "FISH" will always appear in the string "SHELLFISH" so how can I distinguish between the two?
Please let me know if more information is needed. The variable allergens1 is just a simple string ex.
"CONTAINS: EGG, FISH(SALMON), SHELLFISH(OYSTERS)"
I need to work within the confines of the labeling software which actually uses VBScript. I'm sorry for any confusion.
THANK YOU TO EVERYONE WHO HELPED WITH THIS! The final working code is below and should be noted will work with older version of Nicelabel that still use VBScript for label functions:
'''
Private Function GetWords(sText)
GetWords =
Split(Trim(Replace(Replace(Replace(Replace(Replace(Replace(sText, ":", " "), ",", " "), "(", " "), ")", " "), " ", " "), " ", " ")))
End Function
Dim vElem
dim a
a = label.SetObjectVisible("TREENUT",false)
a = label.SetObjectVisible("EGG",false)
a = label.SetObjectVisible("SOY", false)
a = label.SetObjectVisible("WHEAT", false)
a = label.SetObjectVisible("NUT", false)
a = label.SetObjectVisible("SHELLFISH", false)
a = label.SetObjectVisible("FISH", false)
a = label.SetObjectVisible("MILK", false)
a = label.SetObjectVisible("SESAME", false)
a = label.SetObjectVisible("SULFITE", false)
For Each vElem In GetWords(Allergens1)
a = label.SetObjectVisible(vElem,True)
Next
'''

I'm pretty new myself so grain of salt and whatnot, but I think that first I'd split the string into several strings using the comma as a separator and making it a list of ingredients that you can then use your if statement on

A simple substring search over the whole string will not suffice, as you have discovered. You need to "tokenize" your string, ie split the string:
"EGG, FISH(SALMON), SHELLFISH(OYSTERS)"
into separate substrings:
"EGG"
"FISH"
"SALMON"
"SHELLFISH"
"OYSTERS"
And then you can iterate and compare each substring as-is as needed.

The approach I would take, as mentioned by several people, is to tokenize your string and then have your display logic use that list of tokens. Something like the following:
Dim Description
Dim Allergens
Description = "CONTAINS: EGG, FISH(SALMON)"
WScript.Echo Description
Set Allergens = GetAllergens(Description)
DisplayAllergens Allergens
WScript.Echo ""
Description = "CONTAINS: EGG, SHELLFISH(OYSTERS)"
WScript.Echo Description
Set Allergens = GetAllergens(Description)
DisplayAllergens Allergens
WScript.Echo ""
Description = "CONTAINS: EGG, FISH(SALMON), SHELLFISH(OYSTERS)"
WScript.Echo Description
Set Allergens = GetAllergens(Description)
DisplayAllergens Allergens
WScript.Echo ""
Private Function GetAllergens(ByVal Description)
Dim Allergens
Dim Allergen
Dim i
Set GetAllergens = CreateObject("Scripting.Dictionary")
Description = Replace(Description, "CONTAINS: ", "")
Allergens = Split(Description, ",")
For i = LBound(Allergens) To UBound(Allergens)
Allergen = Trim(Split(Allergens(i), "(")(0))
GetAllergens.Add Allergen, Allergen
Next
End Function
Private Sub DisplayAllergens(ByVal Allergens)
Dim Allergen
For Each Allergen In Allergens
If Allergen = "EGG" Then WScript.Echo "EGG picture"
If Allergen = "SHELLFISH" Then WScript.Echo "SHELLFISH picture"
If Allergen = "FISH" Then WScript.Echo "FISH picture"
Next
End Sub
Here is the result:

Here is a one-liner which splits your string into words:
Private Function GetWords(sText)
GetWords = Split(Trim(Replace(Replace(Replace(Replace(Replace(Replace(sText, ":", " "), ",", " "), "(", " "), ")", " "), " ", " "), " ", " ")))
End Function
You can use this with For Each like this:
Dim Allergens1
Dim vElem
Allergens1 = "CONTAINS: EGG, FISH(SALMON), SHELLFISH(OYSTERS)"
For Each vElem In GetWords(Allergens1)
WScript.echo vElem & " picture"
Next
. . . to get this:
CONTAINS picture
EGG picture
FISH picture
SALMON picture
SHELLFISH picture
OYSTERS picture

Related

Replace string into define variable in VB6

I have the code to replace the string of the predetermined variable, but it seems my code is not efficient, because if more strings that want to be replace, the more replace functions, how do I handle this?
Dim appName As String
Dim appVer As String
Dim desc As String
appName = "MyProject"
appVer = App.Major & "." & App.Minor & "." & App.Revision
desc = "{appName} {appVer} is free program"
desc = Replace(desc, "{appName}", appName)
desc = Replace(desc, "{appVer}", appVer)
Label1.Caption = desc
Thanks for help
I answer my question
Public Function ReplaceString(sString As String) As String
Const Tag1 = "{"
Const Tag2 = "}"
Dim sItem() As String, i As Long
sString = Replace(sString, "\n", vbNewLine) 'Replace new line
sItem = Split(sString, Tag1)
For i = 1 To UBound(sItem)
sItem(i - 1) = Split(sItem(i), Tag2, 2)(0)
Next
ReDim Preserve sItem(UBound(sItem) - 1)
For i = 0 To UBound(sItem)
sString = Replace(sString, "{" & sItem(i) & "}", CallByName(Me, sItem(i), VbGet))
Next
ReplaceString = sString
End Function
Hope this will help other in same case

How to display length of word count in vb?

So I've been trying for hours to figure out how to display the length of word count in vb.
For example, if I type in a sentence in a rich textbox and I click a button, I want a form to show up listing the number of one-letter words, two-letter words, three-letter words and so on within that sentence. The number of words of specific length will be outputted in labels, of course.
I found this short code online for word count:
dim wordcount as integer
dim a as string() = RichText.Text.Split(" ")
wordcount = a.length
However, I'm not sure if this code can be used to get the length of word count. Any ideas of how I can achieve outputting the number of words of a specific length in a label? Thank you.
What about something like:
Private Sub mnuCount_Click()
Const DELIMITERS As String = vbNewLine & " !"",.:;?"
Dim WordCounts(1 To 100) As Long
Dim Msg As String
Dim I As Integer
Dim WordCount As Long
With RTB
.Visible = False
.SelStart = 0
Do
.UpTo DELIMITERS, vNegate:=True
.Span DELIMITERS, vNegate:=True
If .SelLength > 0 Then
WordCounts(.SelLength) = WordCounts(.SelLength) + 1
.SelStart = .SelStart + .SelLength
Else
Exit Do
End If
Loop
.SelStart = 0
.Visible = True
End With
Msg = "Length" & vbTab & "Count"
For I = 1 To 100
If WordCounts(I) > 0 Then
Msg = Msg & vbNewLine _
& CStr(I) & vbTab & CStr(WordCounts(I))
WordCount = WordCount + WordCounts(I)
End If
Next
Msg = Msg & vbNewLine _
& "Grand total:" & vbNewLine _
& vbTab & CStr(WordCount)
MsgBox Msg
End Sub
Pradnya's code, translated to VB6:
Option Explicit
Private Sub Command1_Click()
Dim str As String
Dim splitStr() As String
Dim i As Integer
str = "ABC DEF GHIJ KLMNOPQ"
splitStr = Split(str, " ")
MsgBox "Number of words = " & UBound(splitStr) + 1 & vbCrLf & _
"Average Length = " & Len(Replace(str, " ", "")) / (UBound(splitStr) + 1)
End Sub
I made a few simplifications as well. There's no need to go through the loop to get the average. All you have to do to get the length of the whole is remove the spaces and divide by the number of elements in the array.
However, if you want to get a count of the number of words of each length, you'll have to loop through the array, getting the length of each word and storing those values one by one. Best way to do that is to set a reference to scrrun.dll (Windows Scripting Runtime) and use a Dictionary object to store the values.

VB6 categorize search function

If I have a text file that contains the below information, what is the best way to search for the version, for example on system1 only? (in vb6 code, can I use InStr?)
[system1]
version=xx
date=xx
[system2]
version=xx
date=xx
The sample file looks like a standard INI file. You can read these using the GetPrivateProfileString() and related functions. You can also enumerate the sections and values using GetPrivateProfileSectionNames() and GetPrivateProfileSection().
Supposing there is a space after the version and before date (str would be your text):
Dim version As String
version = Mid(str, InStr(str, "version") + 8)
version = Mid(version, 1, InStr(version, " "))
But there are a bunch of functions to parse .ini files out there.
I created a text file "C:\MYFILE.TXT" and this is the content of the file:
[system1]
version=aa
date=bb
[system2]
version=yy
date=zz
[system3]
date=4
[system4]
[system5]
As you can see, I made all possible situation, ie. a system with version info, a system with no version info, etc. Then I wrote this code:
Here is one way to look for a value under a categorized list:
Dim mySystem As String
Dim myVersion As String
mySystem = "[system2]" 'Replace this with the system you are looking for
Dim strTmp As String
Dim SystemFound As Boolean
Dim VersionFound As Boolean
Open "c:\myfilename.txt" For Input As #1
Do While Not EOF(1)
Line Input #1, strTmp
If InStr(UCase(strTmp), UCase(mySystem)) > 0 Then
SystemFound = True
strTmp = ""
Do While Not EOF(1) And InStr(strTmp, "[") = 0
Line Input #1, strTmp
If InStr(UCase(strTmp), "VERSION") > 0 Then
VersionFound = True
myVersion = Mid(strTmp, InStr(strTmp, "=") + 1, Len(strTmp))
End If
Loop
Exit Do
End If
Loop
Close #1
If SystemFound And VersionFound Then
MsgBox "The Version of " & mySystem & " is " & myVersion
ElseIf SystemFound And Not VersionFound Then
MsgBox "The system " & mySystem & " has no version definition"
ElseIf SystemFound = False Then
MsgBox "The system " & mySystem & " is not found in file"
End If

MS Access 2007 VBA: validating text field with VBA and Chr()

I am trying to validate entry of a form field using the following VBA. This works very well. My problem is this Access app creates a variety of XML data files, and I don't want certain characters within that xml....namely soft-returns (Shift+Enter). I believe that the Chr for this is Chr(11), but I don't think I can just add , Chr(11)) to the end of the array below and this will work...how can I use Chr(#) in link manner?
Dim i, j As Integer
dim myField as variant
varNo = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
If IsNull(Me.FieldValue) = False Then
myField = Me.FieldValue
For i = 0 To UBound(varNo)
j = InStr(1, myField , varNo(i))
If j > 0 Then
MsgBox "Cannot use character:" & Chr(13) & Chr(10) & Chr(13)
& Chr(10) & varNo(i), vbCritical, " Illegal Character"
Exit Sub
Exit For
End If
Next
End If
again the above works great for those things in the array, but I would like to include Chr() as well.
You can build your array with an empty string as the new last element, then change the value of the last element to Chr(11).
varNo = Array("\", "/", ":", "*", "?", """", "<", ">", "|", "")
varNo(UBound(varNo)) = Chr(11)
Actually, I'm unsure why that should be necessary. This works for me ...
varNo = Array("\", "/", ":", "*", "?", """", "<", ">", "|", Chr(11))
Based on the comments, I think it will be useful to confirm the text you're evaluating actually contains the characters you expect. Feed the text to this procedure and examine its output in the Immediate window.
Public Sub AsciiValues(ByVal pInput As String)
Dim i As Long
Dim lngSize As Long
lngSize = Len(pInput)
For i = 1 To lngSize
Debug.Print i, Mid(pInput, i, 1), Asc(Mid(pInput, i, 1))
Next
End Sub
Here are a few notes on another approach:
'' Microsoft VBScript Regular Expressions library
'' or CreateObject ("VBScript.RegExp")
Dim rex As New RegExp
With rex
.MultiLine = False
.Global = True
.IgnoreCase = False
End With
'A line for testing
sLine = "abc" & Chr(11)
'Anything that is NOT a-zA-Z0-9 will be matched
rex.Pattern = "[^a-zA-Z0-9]"
If rex.Test(sLine) Then
Debug.Print "Problem: include only alpha numeric"
End If

Remove parts of a string and copy the rest back to a file with vbscript

I would like to remove the unwanted text from each string in a file.
the input string looks like this
username^time stamp^don't need this printed on printer name more useless info pages printed:some number
I want to remove everything else but keep the username,time stamp,printer name and some number.Then write each line to a file so the output looks like this
username timestamp printername some number
This is the code I'm working with
Set fs = CreateObject("Scripting.FileSystemObject")
sf = "C:\test.txt"
Set f = fs.OpenTextFile(sf, 1) ''1=for reading
s = f.ReadAll
segments = Split(s,"^",-1)
s= segments(1,)
f.Close
Set f = fs.OpenTextFile(sf, 2) ''2=ForWriting
f.Write s
f.Close
There's always a moment that somebody asks "Why not use a regular expression?". This is that moment.
Try this:
Dim re, s, match, matches
s = "Chuck Norris^12-12-2012^don't need this printed on HAL9000 more useless info pages printed:42 "
Set re = new regexp
re.pattern = "(.*)\^(.*)\^.*printed on (\w+).*pages printed:(\d+).*"
re.Global = True
Set matches = re.Execute(s)
Set match = matches(0)
msgbox "username=" & match.submatches(0)
msgbox "time stamp=" & match.submatches(1)
msgbox "printer=" & match.submatches(2)
msgbox "pages printed=" & match.submatches(3)
Neat huh? And I bet you'll figure out how to implement it in your existing code.
Code:
Const csSep = "^"
'username^time^(other arbitrary junk)^printer name^(other arbitrary junk)^page count
Dim sJunk : sJunk = "kurt^01:02:03^some junk^nec p7^nix^123"
WScript.Echo sJunk
Dim aParts : aParts = Split(sJunk, csSep)
Dim sNetto : sNetto = Join(Array(aParts(0),aParts(1),aParts(3),aParts(5)), csSep)
WScript.Echo sNetto
output:
kurt^01:02:03^some junk^nec p7^nix^123
kurt^01:02:03^nec p7^123

Resources