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
Related
I have a CSV with data like below
"01","567 "," ","This is a message"
I need to delete the trailing spaces and spaces in blank fields, while leaving the spaces in between data.
My code:
Dim inStream : Set inStream...
With inStream
.open
.type = 2
.charset = "utf-8"
.loadfromfile src
Dim outStream : Set outStream...
outStream.open
outStream.type = 2
While Not .EOS
arrLine = split(.read, ",")
strLine = trim(arrLine(0))
If ubound(arrLine) > 0 Then
For intField = 1 To ubound(arrLine)
strLine = strLine & "," & trim(arrLine(intField))
Next
End If
outStream.write(strLine)
outStream.savetofile dest, create
WEnd
outStream.close
.close
End With
You can split your CSV line into an array and then loop through and use the 'Trim' function on each item.
There are surprisingly good vbscript examples like this on google.
I have below code in classic asp
str=Request.Form("txt_str")
"txt_str" is text box in a classic asp form page where I am entering below values:
000-00001
000-00001
000-00001
000-00002
response.write str
hence str will be 000-00001 000-00001 000-00001 000-00002
array = split(str,Chr(44))
if str <> "" then
x=empty
for i = 0 to ubound(array)
if array(i) <> "" then
array_2 = split(array(i),chr(13) & chr(10))
for j = 0 to ubound(array_2)
if array_2(j) <> "" then
if x=empty then
x= "'" & array_2(j) & "'"
else
x= x & ",'" & array_2(j) & "'"
end if
end if
next
end if
next
End if
response.write x
hence x will be returned as '000-00001','000-00001','000-00001','000-00002'
I want to remove duplicate values from x and display only it as:
x = '000-00001','000-00002'
How can i achieve this.Any help on this would be appreciated.
Thanks
To remove duplicates of string lists, the best option IMO is to use a Dictionary object. You can use this short function to do the task on a given string array:
Function getUniqueItems(arrItems)
Dim objDict, strItem
Set objDict = Server.CreateObject("Scripting.Dictionary")
For Each strItem in arrItems
objDict.Item(strItem) = 1
Next
getUniqueItems = objDict.Keys
End Function
A simple test:
' -- test output
Dim arrItems, strItem
arrItems = Array("a","b","b","c","c","c","d","e","e","e")
For Each strItem in getUniqueItems(arrItems)
Response.Write "<p>" & strItem & "</p>"
Next
This is a sample for your use case:
' -- sample for your use case
Dim strInput, x
strInput = Request.Form("txt_str")
x = "'" & join(getUniqueItems(split(str, Chr(44))), "','") & "'"
BTW, did you notice that Array and Str are VBScript Keywords, so you may run into issues with using such variable names. Therefore, I think it is common practice in VBScript to use prefixes for variable names.
If it's a ordered list, consider using a variable with last value:
lastval = ""
array = split(str,Chr(44))
if str <> "" then
x=empty
for i = 0 to ubound(array)
if array(i) <> "" then
array_2 = split(array(i),chr(13) & chr(10))
for j = 0 to ubound(array_2)
if array_2(j) <> "" then
if array_2(j) <> lastval then
lastval = array_2(j)
if x=empty then
x= "'" & array_2(j) & "'"
else
x= x & ",'" & array_2(j) & "'"
end if
end if
end if
next
end if
next
End if
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.
I have text files that are approximately 6MB in size. There are some lines that contain the NULL (Chr(0))character that I would like to remove.
I have two methods to do this: using Asc()=0 but this takes approximately 50s to complete, the other method uses InStr (line, Chr(0)) =0 (fast ~ 4sec)but the results remove vital info from the lines which contain the NULL characters.
First line of text file as example:
##MMCIBN.000NULL7NULL076059NULL7653NULL1375686349NULL2528NULL780608NULL10700NULL\NULL_NC_ACT.DIR\CFG_RESET.INI
First method (works but VERY slow)
function normalise (textFile )
Set fso = CreateObject("Scripting.FileSystemObject")
writeTo = fso.BuildPath(tempFolder, saveTo & ("\Output.arc"))
Set objOutFile = fso.CreateTextFile(writeTo)
Set objFile = fso.OpenTextFile(textFile,1)
Do Until objFile.AtEndOfStream
strCharacters = objFile.Read(1)
If Asc(strCharacters) = 0 Then
objOutFile.Write ""
nul = true
Else
if nul = true then
objOutFile.Write(VbLf & strCharacters)
else
objOutFile.Write(strCharacters)
end if
nul = false
End If
Loop
objOutFile.close
end function
The output looks like this:
##MMCIBN.000
7
076059
7653
1375686349
2528
780608
10700
\
_NC_ACT.DIR\CFG_RESET.INI
Second method code:
filename = WScript.Arguments(0)
Set fso = CreateObject("Scripting.FileSystemObject")
sDate = Year(Now()) & Right("0" & Month(now()), 2) & Right("00" & Day(Now()), 2)
file = fso.BuildPath(fso.GetFile(filename).ParentFolder.Path, saveTo & "Output " & sDate & ".arc")
Set objOutFile = fso.CreateTextFile(file)
Set f = fso.OpenTextFile(filename)
Do Until f.AtEndOfStream
line = f.ReadLine
If (InStr(line, Chr(0)) > 0) Then
line = Left(line, InStr(line, Chr(0)) - 1) & Right(line, InStr(line, Chr(0)) + 1)
end if
objOutFile.WriteLine line
Loop
f.Close
but then the output is:
##MMCIBN.000\CFG_RESET.INI
Can someone please guide me how to remove the NULLS quickly without losing information. I have thought to try and use the second method to scan for which line numbers need updating and then feed this to the first method to try and speed things up, but quite honestly I have no idea where to even start doing this!
Thanks in advance...
It looks like the first method is just replacing each NULL with a newline. If that's all you need, you can just do this:
Updated:
OK, sounds like you need to replace each set of NULLs with a newline. Let's try this instead:
strText = fso.OpenTextFile(textFile, 1).ReadAll()
With New RegExp
.Pattern = "\x00+"
.Global = True
strText = .Replace(strText, vbCrLf)
End With
objOutFile.Write strText
Update 2:
I think the Read/ReadAll methods of the TextStream class are having trouble dealing with the mix of text and binary data. Let's use an ADO Stream object to read the data instead.
' Read the "text" file using a Stream object...
Const adTypeText = 2
With CreateObject("ADODB.Stream")
.Type = adTypeText
.Open
.LoadFromFile textFile
.Charset = "us-ascii"
strText = .ReadText()
End With
' Now do our regex replacement...
With New RegExp
.Pattern = "\x00+"
.Global = True
strText = .Replace(strText, vbCrLf)
End With
' Now write using a standard TextStream...
With fso.CreateTextFile(file)
.Write strText
.Close
End With
I tried this method (update2) for reading a MS-Access lock file (Null characters terminated strings in 64 byte records) and the ADODB.Stream didn't want to open an already in use file. So I changed that part to :
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(Lfile)
z = f.Size
set ts = f.OpenAsTextStream(ForReading, 0) 'TristateFalse
strLog = ts.Read(z)
ts.Close
set f = nothing
' replace 00 with spaces
With New RegExp
.Pattern = "\x00+"
.Global = True
strLog = .Replace(strLog, " ")
End With
' read MS-Access computername and username
for r = 1 to len(strLog) step 64
fnd = trim(mid(strLog,r, 32)) & ", " & trim(mid(strLog,r+32, 32)) & vbCrLf
strRpt = strRpt & fnd
next
I have an old function in VBScript for Classic ASP that strips out illegal characters when a form is submitted, but it's also stripping out foreign characters and replacing them with junk like A*#L, etc.
The function looks like this:
Private Function stripillegal(fieldcontents)
if isnull(fieldcontents) then
stripillegal = ""
else
Dim stripped, stripillegal_c, stripillegal_i
stripped = ""
if isempty(fieldcontents) then fieldcontents = ""
fieldcontents = CStr( fieldcontents )
fieldcontents = Trim( fieldcontents )
if Len(fieldcontents)>0 then
for stripillegal_i = 1 to Len(fieldcontents)
stripillegal_c = asc(mid(fieldcontents, stripillegal_i, 1))
select case stripillegal_c
case 39
stripped = stripped & "'"
case 37
stripped = stripped & "%"
case 34 ' quote (34)
stripped = stripped & """
case else
stripped = stripped & chr(stripillegal_c)
end select
' response.write stripped & "<br>"
next
end if
stripped = trim(stripped)
while Right(stripped, 1) = chr(13) OR Right(stripped, 1) = chr(10)
stripped = left(stripped, len(stripped)-1)
wend
stripillegal = stripped
end if
End Function
I'm wondering how to tell it to allow foreign characters like those found in French or Spanish.
Regular Expressions can clean these strings up nicely while avoiding foreign characters.
More specificly, this function:
Function strClean (strtoclean)
Dim objRegExp, outputStr
Set objRegExp = New Regexp
objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = "[(?*"",\\<>&#~%{}+_.#:\/!;]+"
outputStr = objRegExp.Replace(strtoclean, "-")
objRegExp.Pattern = "\-+"
outputStr = objRegExp.Replace(outputStr, "-")
strClean = outputStr
End Function