validation of comma and other characters - vba

This is my sample File !
col1,col2,colx,col3,col4,col5
1,A,,AA,X,Y
2,B,,,*/;wBB,D --invalid or bad
3,E,,,....;*()//FF,Y --invalid or bad
4,G,,,.,;'()XX,P --invalid or bad
5,P,Kk,,...(),D
After following Instruction from here I have
2,B,,,BB,D
3,E,,,FF,Y
4,G,,,XX,P
As bad data in a Csv file my task is to validate records through splitting each column and check for a extra delimiter,if found remove the delimiter
I tried this !
Sub File validation()
Dim goFS: Set goFS = CreateObject("Scripting.FileSystemObject") ' (2)
Dim tsIn: Set tsIn = goFS.OpenTextFile("....bad.csv")
Do Until tsIn.AtEndOfStream
sLine = tsIn.ReadLine()
If sLine = EOF then exit else Loop ' I get a error here
Dim str : strconv(sLine) 'error
End Sub
Function strConv(ByVal str As String) As String
Dim objRegEx As Object, allMatches As Object
Set objRegEx = CreateObject("VBScript.RegExp")
With objRegEx
.MultiLine = False
.IgnoreCase = False
.Global = True
.Pattern = ",,,"
End With
strConv = objRegEx.Replace(str, ",,")
End Function
I need a solution with or without Regex to validate this file and put back into source file!
I am very new to to vba scripting can somebody Help me!
After validation I need file to look something like this
col1,col2,colx,col3,col4,col5
1,A,,AA,X,Y
2,B,,BB,D,
3,E,,FF,Y,
4,G,,XX,P,
5,P,Kk,,,D

Are you saying that rows without a value for colX are "bad"? It appears they just have no value. Regardless, you can check for a value in colX easily enough.
Do While Not tsIn.AtEndOfStream
' Read and split the line...
a = Split(tsIn.ReadLine, ",")
' Check for a value in "colX"...
If Len(Trim(a(2))) = 0 Then
' Not sure what you want to do here. Replace it with another value?
a(2) = "0"
End If
' Write the line to another file...
tsOut.WriteLine Join(a, ",")
Loop

An 'experimental function' (see here) to work out the RegExp for converting bad to good lines:
Function demoRegExp()
demoRegExp = 0
Dim aTests : aTests = Array( _
"2,B,,,BB,D", "2,B,,BB,D," _
, "3,E,,,FF,Y", "3,E,,FF,Y," _
, "field,no comma here,,,what,ever", "field,no comma here,,what,ever," _
)
Dim sC : sC = ","
Dim sF : sF = "[^,]+"
Dim r : Set r = New RegExp
r.Pattern = Join(Array("^(", sF, sC, sF, sC, sC, ")(", sC, ")(", sF, sC, sF, ")$"), "")
WScript.Echo "pattern:", qq(r.Pattern)
Dim i
For i = 0 To UBound(aTests) Step 2
Dim sInp : sInp = aTests(i + 0)
Dim sExp : sExp = aTests(i + 1)
Dim sAct : sAct = r.Replace(sInp, "$1$3$2")
WScript.Stdout.Write qq(sInp) & " => " & qq(sAct)
If sAct = sExp Then
WScript.Echo " ok"
Else
WScript.Echo " Fail - exp:", qq(sExp)
End If
Next
End Function
output:
pattern: "^([^,]+,[^,]+,,)(,)([^,]+,[^,]+)$"
"2,B,,,BB,D" => "2,B,,BB,D," ok
"3,E,,,FF,Y" => "3,E,,FF,Y," ok
"field,no comma here,,,what,ever" => "field,no comma here,,what,ever," ok

Related

Parsing a string in MSAccess VBA with varying numbers of delimiters

In MSAccess VBA, I'm trying to parse a name field into last, first, middle. The problem is that the incoming format is not consistent:
Jones John Q
Doe Jane
Smith Robert X
This is what I'm doing
Dim rsNames As DAO.Recordset
Set rsNames = CurrentDb.OpenRecordset("SELECT * FROM tblInput")
If Not (rsNames.EOF And rsNames.BOF) Then
rsNames.MoveFirst
Do Until rsNames.EOF = True
strFullName = rsNames!Name
intLength = Len(strFullName)
intSpacePos = InStr(strFullName, " ")
strLname = Left(strFullName, intSpacePos - 1)
strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos - 1))
strFname = Trim(strFname)
If Len(strFname) + Len(strLname) + (intSpacePos - 1) < intLength Then
strMI = Right(strFullName, 1)
End If
rsNames.Edit
rsNames!LastName = strLname
rsNames!FirstName = strFname
rsNames!MiddleInitial = strMI
rsNames.Update
rsNames.MoveNext
Loop
Results
LastName: Jones
FirstName: John Q
Middle Initial: Q
LastName: Doe
FirstName: Jane
Middle Initial: E
If I change this line
strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos - 1)) to
strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos), the lines with middle initials parse correctly, but the lines without middle initials cut off the last character of the first name and move it to the middle initial field (Doe Jan E)
I've tried using split and replace but neither works properly because of the varying numbers of spaces separating the fields. I'm wondering if my only option is to read the string character by character and building the individual fields that way, but before I go down that path, am I missing something obvious? I have no control over the incoming file.
I'll propose you to use split() function, in this manner:
Dim rsNames As DAO.Recordset
Dim strLname As String, strFname As String, strMI As String
Dim i As Integer
Dim x, arr As Variant
Set rsNames = CurrentDb.OpenRecordset("SELECT * FROM tblInput")
If Not (rsNames.EOF And rsNames.BOF) Then
'rsNames.MoveFirst
Do Until rsNames.EOF = True
arr = Split(rsNames!Name)
strLname = ""
strFname = ""
strMI = ""
i = 0
For Each x In arr
If (x <> "") Then
If (i = 0) Then
strLname = x
ElseIf (i = 1) Then
strFname = x
Else
strMI = x
End If
i = i + 1
End If
'
If (i > 2) Then
Exit For
End If
Next
'
rsNames.Edit
rsNames!LastName = strLname
rsNames!FirstName = strFname
rsNames!MiddleInitial = strMI
rsNames.Update
rsNames.MoveNext
Loop
End If
rsNames.Close
Set rsNames = Nothing
We use a loop to find non empty split strings as LastName, FirstName and Middle initial.
This pure VBA code avoids us to use extra VBScript.RegExp replacement.
I would lean towards using RegEx and Split:
Private Sub Test()
Dim strFullName As String
Dim NameParts As Variant
strFullName = "Jones John Q"
With CreateObject("vbscript.regexp")
.Pattern = "\s+"
.Global = True
strFullName = .Replace(strFullName, " ")
End With
NameParts = Split(strFullName, " ")
End Sub
NameParts is an array containing Last, First, and possibly Middle names.
Are First Name and Last Name always in the same position? If so, the use of split can be use to determine the existence of the middle, i may be missing something though, i'd go for
Dim a() As String
a() = Split(s, Chr(32))
strLastName = a(0)
strFirstName = a(1)
If UBound(a) = 2 Then
strMiddle = a(2)
Else
strMiddle = ""
End If
Debug.Print strFirstName, strMiddle, strLastName
or something a bit less elegant
If Len(s) - Len(Replace(s, Chr(32), "")) = 2 Then
strMiddle = Right(s, Len(s) - InStrRev(s, Chr(32)))
End If

Solidworks EPDM API IEdmEnumeratorVariable5::SetVar not working as expected

I'm trying to use IEdmEnumeratorVariable5::SetVar to update some file card variables based on user input into a windows form. My code executes, there are no error messages, the file is checked out and checked back in and the appropriate comment is added to the history; however the variables on the card are not updated.
I have verified by stepping through code at runtime that all variables are populated with the correct (as expected) data. The SetVar procedures all go off without a hitch, but the variables on the data card do not change value - even manually refreshing the folder view has no effect.
Below is my code.
This is an add-in application, written as a class-library project in VB using VS Community 2015, with target framework .NET 4.0.
In efforts to make this question more concise; immediately below I've included just the snippet of code doing the set variables work, then I've also included more code so you can get the whole picture if needed.
JUST THE TIP :
This is the code doing the set variables work:
Dim UserManager As IEdmUserMgr5 = .SourceVault
Dim User As IEdmUser5 = UserManager.GetLoggedInUser
CardComment = UserComment & CardComment
CardDate = Today().ToString("yyMMdd", Globalization.CultureInfo.InvariantCulture)
CardBy = User.Name
CardDisposition = UserDisposition
CardVariables.SetVar(DispositionVariable, "#", CardDisposition)
CardVariables.SetVar(CommentVariable, "#", CardComment)
CardVariables.SetVar(ByVariable, "#", CardBy)
CardVariables.SetVar(DateVariable, "#", CardDate)
CardVariables.Flush()
THE BROADER STROKES :
Class module level variables:
Private Structure CommandInfo
Dim SourceVault As IEdmVault11
Dim SourceCommand As EdmCmd
Dim SourceSelection As System.Array
Dim TargetTemplate As System.String
Dim VerifiedPaths As List(Of String)
End Structure
Private ReceivedCommand As CommandInfo
OnCmd procedure (caller):
Public Sub OnCmd(ByRef poCmd As EdmCmd,
ByRef ppoData As System.Array) Implements IEdmAddIn5.OnCmd
Dim CommandToRun As MenuCommand
Try
With ReceivedCommand
.SourceVault = poCmd.mpoVault
.SourceCommand = poCmd
.SourceSelection = ppoData
'Get the command structure for the command ID
Select Case poCmd.meCmdType
Case EdmCmdType.EdmCmd_Menu
CommandToRun = AvailableCommands(.SourceCommand.mlCmdID)
Case EdmCmdType.EdmCmd_CardButton
Select Case True
Case poCmd.mbsComment.ToString.ToUpper.Contains("DISPOSITION")
DispositionRequest()
Case Else : Exit Sub
End Select
Case Else : Exit Sub
End Select
'...... (End Try, End Sub, Etc.)
DispositionRequest procedure (callee):
Private Sub DispositionRequest()
Dim UserDisposition As String
Using Disposition As New DispositionForm
With Disposition
If Not .ShowDialog() = System.Windows.Forms.DialogResult.OK Then Exit Sub
Select Case True
Case .Approve.Checked
UserDisposition = "Approved"
Case .Reject.Checked
UserDisposition = "Rejected"
Case Else : Exit Sub
End Select
End With
End Using
Dim UserComment As String
Using Explanation As New DispositionExplanation
With Explanation
If Not .ShowDialog() = System.Windows.Forms.DialogResult.OK Then Exit Sub
If .ListView1.Items.Count > 0 Then
'do some stuff not relevant to this question...
End If
UserComment = .Comments.Text
End With
End Using
'This next procedure just gets a list of paths from ReceivedCommand.SourceSelection - which is just the ppoData argument from the OnCmd procedure - see code block above!
Dim RequestPaths As List(Of String) = GetSelectedFilePaths()
For Each Path As String In RequestPaths
With ReceivedCommand
Dim RequestFile As IEdmFile5 = .SourceVault.GetFileFromPath(Path)
Dim ParentFolder As IEdmFolder6 = .SourceVault.GetFolderFromPath(System.IO.Path.GetDirectoryName(Path))
Dim UnlockLater As Boolean = False
If Not RequestFile.IsLocked Then
UnlockLater = True
RequestFile.LockFile(ParentFolder.ID, .SourceCommand.mlParentWnd, CInt(EdmLockFlag.EdmLock_Simple))
End If
Dim CardVariables As IEdmEnumeratorVariable5 = RequestFile.GetEnumeratorVariable
'We allow users to re-disposition a request so we want to keep any previous disposition information so it is not lost
Dim CardComment As String = String.Empty
Dim CardBy As String = String.Empty
Dim CardDate As String = String.Empty
Dim CardDisposition As String = String.Empty
Dim Success As Boolean
Const CommentVariable As String = "DispComm"
Const ByVariable As String = "DisposedBy"
Const DateVariable As String = "DisposedDate"
Const DispositionVariable As String = "Disposition"
Success = CardVariables.GetVar(DispositionVariable, "#", CardDisposition)
If Success Then
Success = CardVariables.GetVar(CommentVariable, "#", CardComment)
If Success Then Success = CardVariables.GetVar(ByVariable, "#", CardBy)
If Success Then Success = CardVariables.GetVar(DateVariable, "#", CardDate)
If Success Then CardComment = "Previously dispositioned as: """ & CardDisposition & """ by: " & CardBy & " on: " & CardDate & vbNewLine &
"---------Previous disposition explanation---------" & vbNewLine & CardComment
End If
Dim UserManager As IEdmUserMgr5 = .SourceVault
Dim User As IEdmUser5 = UserManager.GetLoggedInUser
CardComment = UserComment & CardComment
CardDate = Today().ToString("yyMMdd", Globalization.CultureInfo.InvariantCulture)
CardBy = User.Name
CardDisposition = UserDisposition
CardVariables.SetVar(DispositionVariable, "#", CardDisposition)
CardVariables.SetVar(CommentVariable, "#", CardComment)
CardVariables.SetVar(ByVariable, "#", CardBy)
CardVariables.SetVar(DateVariable, "#", CardDate)
CardVariables.Flush()
If UnlockLater Then RequestFile.UnlockFile(lParentWnd:= .SourceCommand.mlParentWnd,
bsComment:="Dispositioned as " & CardDisposition,
lEdmUnlockFlags:=0)
.SourceVault.RefreshFolder(ParentFolder.LocalPath)
End With
Next
End Sub
From the documentation:
bsCfgName : Name of configuration or layout to which to store the variable value; empty string for folders and file types that do not support configurations
I was working with a virtual file, which did not support configurations.
I saw a C example working with a virtual file and they were passing null references, so I reread the documentation and saw that excerpt above, so I changed my code from "#" to String.Empty for the mboconfiguration argument and now it is working!
CardVariables.SetVar(DispositionVariable, String.Empty, CardDisposition)
CardVariables.SetVar(CommentVariable, String.Empty, CardComment)
CardVariables.SetVar(ByVariable, String.Empty, CardBy)
CardVariables.SetVar(DateVariable, String.Empty, CardDate)
CardVariables.Flush()

VBA: If A found in line 1, and B found in line 2.. then

I currently have my VBA set up to read a text file (using FileSystemObject) and to find certain strings. This all works great. But what I am trying to achieve is for VBA to read through the text and when it finds a certain string (A) and in the next line below it another string (B) it will do something. But only if B is right after A.
Example:
Find in the following text "Bob's House" and in the next line after that "Electricity.
Text 1: - Return False
blablabla *Bob's House* blablabla
blablabla blablabla blablabla
blabla *Electiricity* blablabla
Text 1: - Return True
blablabla *Bob's House* blablabla
blabla *Electiricity* blablabla
This is what I have so far:
Set fsFile = fs.OpenTextFile(FilePath, 1, False)
sLine = fsFile.ReadLine
If VBA.InStr(1, sLine, "Bobs House") > 0 Then
checkpointHeading = True
End If
If VBA.InStr(1, sLine, "Electricity") > 0 Then
checkpointSubheading = True
End If
If checkpointHeading = True And checkpointSubheading = True Then
MsgBox "Found it!"
End If
This returns "Found it" regardless of how many lines there are between Bobs House and Electricity. Which makes sense. But how do I force the second restraint only after the first is found the line before?
Is there something like sLine +1 / .Readline + 1 (and then apply the second if statement inside the first?).
Thanks in advance, R
You are having this trouble because you are not resetting the 'Bob's House' variable on the next line if that line doesn't equal 'Electricity'. So once Bob's House is found it will always be true and it doesn't matter where 'Electricity' comes in.
You can accomplish what you are after one of two ways. Using Booleans like you have and the code in 'Way 1' (which I've bloated out a bit so its easy to follow), or probably a better way where you simply set the current line string variable to a new string variable which holds the previous line at the end of the loop and then check both of these variables next line like in 'Way 2'.
(Note there are a couple of typos in your example which I've retained so the code works with the example).
Sub Way1()
Dim fs As New FileSystemObject, fsfile As Object
Dim sLine As String
Dim checkpointHeading As Boolean, checkpointSubheading As Boolean
'Open file
Set fsfile = fs.OpenTextFile("G:Test.txt", 1, False)
'Loop through
Do While fsfile.AtEndOfStream <> True
sLine = fsfile.ReadLine
If VBA.InStr(1, sLine, "Bob's House") > 0 Then
checkpointHeading = True
Else
'If the line doesn't have Bob's House then check if the line before did
If checkpointHeading Then
'If it did then check for Electricity
If VBA.InStr(1, sLine, "Electiricity") > 0 Then
'If it's found then happy days
checkpointSubheading = True
Else
'If it's not found then reset everything
checkpointHeading = False: checkpointSubheading = False
End If
End If
End If
'Check if we've found it
If checkpointHeading = True And checkpointSubheading = True Then
MsgBox "Found it!"
'You may want to reset here to be safe
checkpointHeading = False: checkpointSubheading = False
End If
Loop
fsfile.Close
Set fsfile = Nothing
Set fs = Nothing
End Sub
The easier and more concise way 2:
Sub Way2()
Dim fs As New FileSystemObject, fsfile As Object
Dim sLine As String, sPrevLine As String
'Open file
Set fsfile = fs.OpenTextFile("G:Test.txt", 1, False)
'Loop through
Do While fsfile.AtEndOfStream <> True
sLine = fsfile.ReadLine
If VBA.Len(sPrevLine) > 0 Then
If VBA.InStr(1, sPrevLine, "Bob's House") > 0 And VBA.InStr(1, sLine, "Electiricity") Then
MsgBox "Found it!"
End If
End If
'Set the current line to the previous line *at the end of the loop*
sPrevLine = sLine
Loop
fsfile.Close
Set fsfile = Nothing
Set fs = Nothing
End Sub
I didn't test it, but this should demonstrate the logic:
Const filepath = "..."
Sub test()
Dim fs
Dim fsFile
Dim found As Boolean
Dim flag As Boolean
Dim sLine As String
Set fs = CreateObject("Scripting.FileSystemObject")
Set fsFile = fs.OpenTextFile(filepath, 1, False)
found = False
flag = False
Do While Not fsFile.AtEndOfStream And Not found
sLine = fsFile.readLine
If flag And InStr(sLine, "Electricity") Then found = True
flag = (InStr(sLine, "Bobs House") > 0)
Loop
If found Then
MsgBox sLine
Else
MsgBox "not found"
End If
End Sub
Edit: Tested.
Something like this:
sLine = fsFile.ReadLine
If isHeading Then
If InStr(1, sLine, "Electricity") > 0 Then
MsgBox "Found It!"
End If
isHeading = False
End If
If InStr(1, sLine, "Bobs House") > 0 Then
isHeading = True
End If

Search for a certain style in word 2010 and make it into a bookmark using vba

How to make a style as a bookmark in word 2010?
You won't be able to use most of the text in the document as the bookmark name. It is just illegal to use certain characters in a bookmark name in Word/VBA. It may be possible to add such characters in bookmark names in an XML format of the document, so if it is required, you can ask a separate question.
This feels like way too much code to post on SO. You really need to explain what framework you have in place and tell us where your hurdles are. We can't do this again. "Works for me". If you have any questions though don't hesitate to ask.
Run the "RunMe" macro at the bottom.
Private Function IsParagraphStyledWithHeading(para As Paragraph) As Boolean
Dim flag As Boolean: flag = False
If InStr(1, para.Style, "heading", vbTextCompare) > 0 Then
flag = True
End If
IsParagraphStyledWithHeading = flag
End Function
Private Function GetTextRangeOfStyledParagraph(para As Paragraph) As String
Dim textOfRange As String: textOfRange = para.Range.Text
GetTextRangeOfStyledParagraph = textOfRange
End Function
Private Function BookmarkNameAlreadyExist(bookmarkName As String) As Boolean
Dim bookmark As bookmark
Dim flag As Boolean: flag = False
For Each bookmark In ActiveDocument.Bookmarks
If bookmarkName = bookmark.name Then
flag = True
End If
Next
BookmarkNameAlreadyExist = flag
End Function
Private Function CreateUniqueBookmarkName(bookmarkName As String)
Dim uniqueBookmarkName As String
Dim guid As String: guid = Mid$(CreateObject("Scriptlet.TypeLib").guid, 2, 36)
guid = Replace(guid, "-", "", , , vbTextCompare)
uniqueBookmarkName = bookmarkName & guid
CreateUniqueBookmarkName = uniqueBookmarkName
End Function
Private Function BookmarkIt(rng As Range, bookmarkName As String)
Dim cleanName As String: cleanName = MakeValidBMName(bookmarkName)
If BookmarkNameAlreadyExist(cleanName) Then
cleanName = CreateUniqueBookmarkName(cleanName)
End If
ActiveDocument.Bookmarks.Add name:=cleanName, Range:=rng
End Function
''shamelessly stolen from gmaxey at http://www.vbaexpress.com/forum/showthread.php?t=37674
Private Function MakeValidBMName(strIn As String)
Dim pFirstChr As String
Dim i As Long
Dim tempStr As String
strIn = Trim(strIn)
pFirstChr = Left(strIn, 1)
If Not pFirstChr Like "[A-Za-z]" Then
strIn = "A_" & strIn
End If
For i = 1 To Len(strIn)
Select Case Asc(Mid$(strIn, i, 1))
Case 49 To 58, 65 To 90, 97 To 122
tempStr = tempStr & Mid$(strIn, i, 1)
Case Else
tempStr = tempStr & "_"
End Select
Next i
tempStr = Replace(tempStr, " ", " ")
MakeValidBMName = tempStr
End Function
Sub RunMe()
Dim para As Paragraph
Dim textOfPara As String
For Each para In ActiveDocument.Paragraphs
If IsParagraphStyledWithHeading(para) Then
textOfPara = GetTextRangeOfStyledParagraph(para)
If para.Range.Bookmarks.Count < 1 Then
BookmarkIt para.Range, textOfPara
End If
End If
Next
End Sub

PDF page count not correct

I was just wondering why the vbs code in the link below is not counting pdf pages correctly? It seems to under count by half or more the number of pages that actually exist in each pdf.
http://docs.ongetc.com/index.php?q=content/pdf-pages-counting-using-vb-script
Here is the code if you can not access the link above:
' By Chanh Ong
'File: pdfpagecount.vbs
' Purpose: count pages in pdf file in folder
Const OPEN_FILE_FOR_READING = 1
Set gFso = WScript.CreateObject("Scripting.FileSystemObject")
Set gShell = WScript.CreateObject ("WSCript.shell")
Set gNetwork = Wscript.CreateObject("WScript.Network")
directory="."
set base=gFso.getFolder(directory)
call listPDFFile(base)
Function ReadAllTextFile(filespec)
Const ForReading = 1, ForWriting = 2
Dim f
Set f = gFso.OpenTextFile(filespec, ForReading)
ReadAllTextFile = f.ReadAll
End Function
function countPage(sString)
Dim regEx, Match, Matches, counter, sPattern
sPattern = "/Type\s*/Page[^s]" ' capture PDF page count
counter = 0
Set regEx = New RegExp ' Create a regular expression.
regEx.Pattern = sPattern ' Set pattern "^rem".
regEx.IgnoreCase = True ' Set case insensitivity.
regEx.Global = True ' Set global applicability.
set Matches = regEx.Execute(sString) ' Execute search.
For Each Match in Matches ' Iterate Matches collection.
counter = counter + 1
Next
if counter = 0 then
counter = 1
end if
countPage = counter
End Function
sub listPDFFile(grp)
Set pf = gFso.CreateTextFile("pagecount.txt", True)
for each file in grp.files
if (".pdf" = lcase(right(file,4))) then
larray = ReadAllTextFile(file)
pages = countPage(larray)
wscript.echo "The " & file.name & " PDF file has " & pages & " pages"
pf.WriteLine(file.name&","&pages)
end if
next
pf.Close
end sub
Thanks
The solution offered (and accepted) will only work for a limited number of PDF documents. Since PDF documents frequently compress large chunks of data including page metadata, crude regular expression searches for "type\s*/page[^s]" will often miss pages.
The only really reliable solution is to very laboriously decompose the PDF document. I'm afraid I don't have a working VBS solution but I have written a Delphi function which demonstrates how to do this (see http://www.angusj.com/delphitips/pdfpagecount.php).
Try this
Function getPdfPgCnt(ByVal sPath)
Dim strTStr
With CreateObject("Adodb.Stream")
.Open
.Charset = "x-ansi"
.LoadFromFile sPath
strTStr = .ReadText(-1)
End With
With (New RegExp)
.Pattern = "Type\s+/Page[^s]"
.IgnoreCase = True
.Global = True
getPdfPgCnt = .Execute(strTStr).Count
End With
If getPdfPgCnt = 0 Then getPdfPgCnt = 1
End Function
'Usage : getPdfPgCnt("C:\1.pdf")
Update #1~#2:
Option Explicit
Private Function getPdfPgCnt(ByVal sPath) 'Returns page count of file on passed path
Dim strTStr
With CreateObject("Adodb.Stream")
.Open
.Charset = "x-ansi"
.LoadFromFile sPath
strTStr = .ReadText(-1)
End With
With (New RegExp)
.Pattern = "Type\s*/Page[^s]"
.IgnoreCase = True
.Global = True
getPdfPgCnt = .Execute(strTStr).Count
End With
If getPdfPgCnt = 0 Then getPdfPgCnt = 1
End Function
'--------------------------------
Dim oFso, iFile
Set oFso = CreateObject("Scripting.FileSystemObject")
'enumerating pdf files in vbs's base directory
For Each iFile In oFso.getFolder(oFso.GetParentFolderName(WScript.ScriptFullName)).Files
If LCase(oFso.GetExtensionName(iFile)) = "pdf" Then WScript.Echo iFile & " has "& getPdfPgCnt(iFile)&" pages."
Next
Set oFso = Nothing
'--------------------------------