vbs type mismatch error 800a000d type mismatch : readfile - file-io

I am new at vbs and am getting a error at the line set arr = readfile( FileName )
I am trying to read an file into an array
and can not figure out what i am doing wrong
Thanks in advance for your assistance
Dim FileName ' File Name to Process
Call MainProcedure
WScript.Quit
Sub MainProcedure
filename = "c:\print\check.bat"
WScript.Echo( "Printing document in progress..." )
WScript.Echo( "Filename ====> " & FileName )
Dim arr, i
i = 0
set arr = readfile( FileName )
For Each present In arr
' user = split(present,",")
' WScript.Echo user(0) & user(1) & user(2) & user(3) & user(4) & "|"
i = i + 1
WScript.Echo present & "|"
Next
End Sub
Sub readfile(strFile)
dim fs,objTextFile
set fs=CreateObject("Scripting.FileSystemObject")
If (fs.FileExists( strFile)) Then
dim userArrayList
set objTextFile = fs.OpenTextFile(strFile)
Set userArrayList = CreateObject( "System.Collections.ArrayList" )
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
userArrayList.add strNextLine
Loop
objTextFile.Close
set objTextFile = Nothing
set fs = Nothing
set readfile = userArrayList
Else
'Alert User
WScript.Echo("File does not exist!")
WScript.Quit()
End If
end Sub

Your
set arr = readfile( FileName )
implies that readfile() is a Function (returning an ArrayList). But you define
Sub readfile(strFile)
...
set readfile = userArrayList
...
end Sub
You may try to change this to
Function readfile(strFile)
...
set readfile = userArrayList
...
End Function
ADDED:
The task "Read a files' lines into an array" can be done in a much more simple way:
cscript fitoar.vbs
0 Option Explicit
1 Dim a : a = Split(CreateObject("Scripting.FileSystemObject").OpenTextFile("fitoar.vbs").ReadAll(), vbCrLf)
2 Dim l
3 For l = 0 To UBound(a)
4 WScript.Echo l, a(l)
5 Next
6

Related

Regex vba script throwing error : runtime error 9 ... Subscript out of range

I have a Word doc with some numbers referred in the foot notes. and I am exporting these references as a csv file.
Sub FindNumber()
Dim exp, exp1 As RegExp
Set exp = New RegExp
exp.Pattern = "\b[A-Za-z]{3}[0-9]{7}\b"
exp.Global = True
Dim splits(1000) As String
Dim x As Long
Dim results As MatchCollection
Set results = exp.Execute(ActiveDocument.StoryRanges(wdFootnotesStory))
x = 1
For Each res In results
splits(x) = res
x = x + 1
Next res
Dim Filename As String, line As String
Dim i As Integer
Filename = "C:\VBA Export" & "\Numbers.csv"
Open Filename For Output As #2
Print #2, "Control Numbers"
For i = LBound(splits) To UBound(splits)
Print #2, splits(i)
Next i
Close #2
MsgBox "Numbers were exported to " & Filename, vbInformation
End Sub
The code above was working fine and just suddenly starting throwing error at 'splits(x) = res'
I have tried checking my regex and I can see that it works fine. If I change splits(x) to splits(6) or something similar it works like a charm .
Can someone please help ?
EDIT - changed code to write matches directly to Excel.
Sub Tester()
Dim oXl As Excel.Application 'add reference to MS Excel object library...
Dim oWb As Excel.Workbook, c As Excel.Range, i As Long, col As Collection
Set oXl = New Excel.Application
oXl.Visible = True
Set oWb = oXl.Workbooks.Add()
Set c = oWb.Worksheets(1).Range("A1")
ListMatchesInExcel ActiveDocument.StoryRanges(wdFootnotesStory), _
"\b[A-Za-z]{3}[0-9]{7}\b", _
"Id Numbers", c
Set c = c.Offset(0, 1)
ListMatchesInExcel ActiveDocument.StoryRanges(wdFootnotesStory), _
"\b[A-Za-z]{2}[0-9]{9}\b", _
"Other Numbers", c
Set c = c.Offset(0, 1)
'etc etc
End Sub
'Search through `SearchText` for text matching `patt` and export all
' matches to Excel with a header `HeaderText`, starting at range `c`
Sub ListMatchesInExcel(SearchText As String, patt As String, _
headerText As String, c As Excel.Range)
'add reference to MicroSoft VBscript regular expressions
Dim exp, exp1 As RegExp, col As New Collection
Dim results As MatchCollection, res As Match, i As Long
Set exp = New RegExp
exp.Pattern = patt
exp.Global = True
Set results = exp.Execute(SearchText)
'log to Immediate pane
Debug.Print (col.Count - 1) & " matche(s) for '" & patt & "'"
c.Value = headerText
i = 1
For Each res In results
c.Offset(i).Value = res
i = i + 1
Next res
c.EntireColumn.AutoFit
End Sub

List Contents of a zip(TAR) file using VBA

I trying to write much larger code to email a list of files in a TAR file and then send it in an email but the last thing i am struggling with is the actual listing of the contents of the TAR file. the code I have tried so far is:
Public r As Long
Sub Test()
Dim strPath As String
Dim sh, n, x, i
'Change Path To Suit
'strPath = ThisWorkbook.Path & "\"
strPath = "H:\99 - Temp\"
Set sh = CreateObject("Shell.Application")
x = GetFiles(strPath, "*.TAR", True)
r = 7
For Each i In x
Set n = sh.NameSpace(i) <----------
Recur sh, n
Next i
End Sub
Sub Recur(sh, n)
Dim i, subn, x As Long, p As Long
For Each i In n.Items
If i.isfolder Then
Set subn = sh.NameSpace(i)
Recur sh, subn
Else
p = LastPos(i.Path, "\")
Debug.Print Mid(i.Path, p + 1)
'Cells(r, 1) = Mid(i.Path, p + 1)
r = r + 1
End If
Next i
End Sub
Function GetFiles(StartPath As String, FileType As String, SubFolders As Boolean) As Variant
StartPath = StartPath & IIf(Right(StartPath, 1) = "\", vbNullString, "\")
GetFiles = Split(Join(Filter(Split(CreateObject("WScript.Shell").Exec("CMD /C DIR """ & StartPath &
FileType & """ " & IIf(SubFolders, "/S", vbNullString) & " /B /A:-D").StdOut.ReadAll, vbCrLf), ":"),
"#"), "#")
End Function
Function LastPos(strVal As String, strChar As String) As Long
LastPos = InStrRev(strVal, strChar)
End Function
But I can a runtime error '-2147467259 (80004005)':
Method 'NameSpace of Object 'IShellDispatch6' failed
so I tried this one:
Sub test99()
Dim n As Variant
Set sh = CreateObject("shell.application")
Set n = sh.NameSpace("H:\99 - Temp\test.TAR")
For Each i In n.Items <-------------
Debug.Print i.Path
Next
End Sub
which returns another run-time error 91:
Object variable or with block variable not set.
I am comfortable with VBA but really struggling to integrate shell.
ideally the end goal is to get the file open window, select the TAR file that I need read (it's not always in the same folder so need it flexible) and then list the files in the TAR.
Thank you
Using ShellRun concept from here: Capture output value from a shell command in VBA?
Working on Win10
Sub tester()
Dim p, s, col, e
p = "C:\Blah\Temp\Temp.tar"
Set col = ShellOutput("tar -tf """ & p & """")
Debug.Print col.Count; " entries returned"
Debug.Print "--------------------"
For Each e In col
Debug.Print e
Next e
End Sub
'Run a shell command, returning the output as a collection of lines
Public Function ShellOutput(sCmd As String) As Collection
Dim sLine, col As Collection
Set col = New Collection
With CreateObject("WScript.Shell").Exec(sCmd).StdOut
While Not .AtEndOfStream
sLine = .ReadLine
If sLine <> "" Then col.Add sLine
Wend
End With
Set ShellOutput = col
End Function

DDE - Mail Merge From Excel to Word 2016 using OpenDataSource

I have a old legacy code which is programmed for mail merge. I have a add-in code to populate xls file which in turn should merge the data to word template defined. Code snippet :
Public Sub ProcessForSharePoint(DataSource As Object, MainDoc As Document)
Dim tempPath As String
Dim i As Integer
Dim recordCount As Integer
Dim ActualCount As Integer
Dim ws As Variant
Dim tempName As String
Dim rowEmpty As Boolean
On Error GoTo tempFileError
tempName = Left(MainDoc.name, InStrRev(MainDoc.name, ".") - 1)
tempPath = Environ("TEMP") + "\" + tempName + ".xls"
If (Dir(tempPath) <> "") Then
SetAttr tempPath, vbNormal
Kill tempPath
End If
DataSource.SaveAs (tempPath)
On Error GoTo openDataSourceError
MainDoc.MailMerge.OpenDataSource tempPath, ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True,
AddToRecentFiles:=False, Revert:=False, Connection:="Entire Spreadsheet", SubType:=wdMergeSubTypeWord2000
recordCount = 0
On Error GoTo wsError
Set ws = DataSource.WorkSheets(1)
Dim r As Integer
Dim c As Integer
' Work out how many rows we have to process
For r = 2 To ws.UsedRange.Rows.Count
rowEmpty = True
For c = 1 To ws.UsedRange.Columns.Count
If Not IsEmpty(ws.Cells(r, c)) Then
rowEmpty = False
Exit For
End If
Next c
If rowEmpty Then
Exit For
End If
recordCount = recordCount + 1
Next r
GoTo DoMerge
wsError:
GoTo CloseMerge
DoMerge:
ActualCount = 0
If (recordCount = 0) Then
OutputDebugString "PSLWordDV: ProcessForSharePoint: No records to process"
GoTo CloseMerge
End If
On Error GoTo mergeError
For i = 1 To recordCount
' .Destination 0 = DOCUMENT, 1 = PRINTER
MainDoc.MailMerge.Destination = 0 'wdSendToNewDocument
MainDoc.MailMerge.SuppressBlankLines = True
With MainDoc.MailMerge.DataSource
.FirstRecord = i 'wdDefaultFirstRecord
.LastRecord = i 'wdDefaultLastRecord
.ActiveRecord = i
End With
MainDoc.MailMerge.Execute Pause:=False
Populate MainDoc, ActiveDocument
ActualCount = ActualCount + 1
Next i
GoTo CloseMerge
When I call this function, my xls files gets open and populate data (I want data from Sheet 1 only). Then my WORD opens (OpenDataSource) and on selection of "Yes" for population on Word --> My code fails and catches the error "462".
On further analysis (not sure correct or not), it seems, there is a problem in :
Set ws = DataSource.WorkSheets(1)
NOTE: If I hard code my recordCount variable to 1 (say) -> merging process works absolutely fine.
Can anyone please help on priority to sort my client issue please.

How to fast compare Corel file by its content using Corel VBA not to open files

I am trying to compare files by objects to find dublicate. I have 2900 files in folder and i need to check them all. In other words I have to run compare methods 2900*2900 times and every time when comparing two file I need to open and close 1 of those. If there is a way to work with Corel files not to open them? or is it posible to get metadata\metadata.xml from Corel VBA files to check and compare some parametrs from it such as Objects(shapes) count?
I am in despered...
I am using this logic system
Private Sub CommandButton1_Click()
Dim Folder As String
MousePointer = fmMousePointerHourGlass
Folder = BrowseForFolderDlg("o:\", "Select Source Folder", GetWindowHandle("ThunderDFrame", Me.Caption))
tb_inputFolder.text = Folder
End Sub
Private Sub CommandButton2_Click()
Dim fso As Object
Dim objFolder As Object
Dim objFileList As Object
Dim vFile, vFile1 As Variant
Dim inputFolder As String, outputFolder As String
inputFolder = tb_inputFolder.text 'input folder
If (inputFolder = "") Then
Exit Sub
End If
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFolder = fso.GetFolder(inputFolder)
Set objFileList = objFolder.Files
Dim currentFile As String
Dim dunFiles() As String
Dim arrLength As Integer
ReDim Preserve dunFiles(1)
arrLength = 1
dunFiles(0) = ""
For Each vFile In objFileList
Dim doc As Document, doc1 As Document, buf As String
Dim fName As String
fName = (Left(vFile.name, Len(vFile.name) - 4))
buf = Right(vFile.path, 3)
If (buf = "cdr" And findArrayElement(dunFiles, arrLength, vFile.name) = -1) Then
Set doc = OpenDocument(vFile.path) 'document opend
dunFiles(arrLength - 1) = vFile.name
ReDim Preserve dunFiles((arrLength + 1))
arrLength = arrLength + 1
For Each vFile1 In objFileList
buf = Right(vFile1.path, 3)
If (vFile1.name = currentFile Or findArrayElement(dunFiles, arrLength, vFile1.name) <> -1 Or buf <> "cdr") Then
GoTo nextElement
End If
'Set doc1 = OpenDocument(vFile1.path) 'document opend
Dim res As Variant
res = writeFile(doc.FileName + " VS " + vFile1.name + " " + Str(Now), doc.FilePath + "compare.log")
If (compareDocs(doc, vFile1.path)) Then
dunFiles(arrLength - 1) = fName + "_" + vFile1.name
ReDim Preserve dunFiles((arrLength + 1))
arrLength = arrLength + 1
Dim name As String
name = vFile.ParentFolder.path + "\" + fName + "_" + vFile1.name
Name vFile1.path As name
res = writeFile(vFile.ParentFolder.path + "\" + fName + " the same as " + name, doc.FilePath + "rename.log")
End If
'doc1.Close
nextElement:
Next vFile1
doc.Close
End If
' doc.Close 'close document
Next vFile
lb_info.Caption = "Finished! Press exit"
End Sub
Private Function findArrayElement(inputArray() As String, inputLen As Integer, element As String)
Dim e As String
Dim i As Integer
findArrayElement = -1
For i = 0 To inputLen - 1
If (inputArray(i) = element) Then
findArrayElement = i
Exit Function
End If
Next i
End Function
Private Function compareDocs(doc As Document, path2 As String)
Dim doc1 As Document
Dim e1 As Shape, e2 As Shape, elements() As String
Dim sameShapesCount As Integer
sameShapesCount = 0
ReDim elements(1) As String
elements(0) = ""
Set doc1 = OpenDocument(path2) 'document opend
compareDocs = False
lb_info.Caption = "Comapre " + doc.FullFileName + " with " + path2
For Each e1 In doc.SelectableShapes
e1.UngroupAll
Next e1
For Each e2 In doc1.SelectableShapes
e2.UngroupAll
Next e2
If (doc.SelectableShapes.Count <> doc1.SelectableShapes.Count) Then
doc1.Close
Exit Function
End If
For Each e1 In doc.SelectableShapes
'If (findArrayElement(elements, (UBound(elements) + 1), Str(e1.StaticID)) = -1) Then
'ReDim Preserve elements(UBound(elements) + 1) As String
'elements(UBound(elements)) = e1.StaticID
For Each e2 In doc1.SelectableShapes
If (findArrayElement(elements, (UBound(elements) + 1), "2_" + Str(e2.StaticID)) = -1) Then
If (e1.CompareTo(e2, cdrCompareShapeType, cdrCompareEquals)) Then
If (e1.CompareTo(e2, cdrCompareFillType, cdrCompareEquals)) Then
If (e1.CompareTo(e2, cdrCompareOutline, cdrCompareEquals)) Then
If (e1.CompareTo(e2, cdrCompareOutlineColor, cdrCompareEquals)) Then
If (e1.CompareTo(e2, cdrCompareOutlineWidth, cdrCompareEquals)) Then
'If (e1.CompareTo(e2, cdrCompareShapeHeight, cdrCompareEquals)) Then
If (e1.CompareTo(e2, cdrCompareFil, cdrCompareEquals)) Then
'If (e1.CompareTo(e2, cdrCompareShapeWidth, cdrCompareEquals)) Then
ReDim Preserve elements(UBound(elements) + 1) As String
elements(UBound(elements)) = "2_" + Str(e2.StaticID)
sameShapesCount = sameShapesCount + 1
GoTo nextElement1
'End If
End If
'End If
End If
End If
End If
End If
End If
End If
Next e2
'End If
nextElement1:
Next e1
If (doc.SelectableShapes.Count = sameShapesCount) Then
compareDocs = True
End If
doc1.Close
End Function
Private Function writeFile(text As String, path As String)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim oFile As Object
If Not Dir(path, vbDirectory) = vbNullString Then
Set oFile = fso.OpenTextFile(path, 8)
Else
Set oFile = fso.CreateTextFile(path, 0)
End If
oFile.WriteLine text
oFile.Close
Set fso = Nothing
Set oFile = Nothing
End Function
The main problem is that the "open process" can last up to few minutes and to check 2k corel fiels I need a YEAR
In a first pass, open each file once.
Go over the data you care about -- object count or whatever -- that must be equal.
From this data, build a hash -- a pseudo-random value that combines information from each of them.
Build a table that maps from the hash to a set of draw files that match the hash.
Now you only have to compare files which have a the same hash value, not every pair of files. A well designed hash and data to feed it should reduce your collision rate to nearly zero.
This should speed up your program by a factor of 1000 to 3000 or so.
To ensure that the hash/collision works well, your first pass should just hash and print out the lists of collisions.
Sort the list by filesize. Only compare files that are similar in size. You can use dir to generate a sorted list by size.
You only need to open each file once. Hash each file (maybe an alphabetically list of object names). Store and sort and dupes are the same objects.
You can use excel if it's a one off, or a recordset if you need to do it in code.

Read and copy text files by date into active worksheet

I'm trying to create a macro that reads each *.txt file from a folder, and if the modification date matches the current one, copy the contents into a worksheet of the *.xls file. I've been checking a lot of the codes you have been sharing here, but I just can't make it work.
When debbuging, at the 8th line, I get an error:
438: Object doesn't support this property or method
Sub GetSAPfiles()
Dim Cont As Integer
Dim RootDir As String
RootDir = "\HOME\SAP\dir\"
SAPfile = Dir(RootDir)
Set SAPfile = CreateObject("Scripting.FileSystemObject")
Set SF = SAPfile.GetFile(RootDir + SAPfile)
Do While SAPfile <> ""
Dim ObjDate, CurrDate
CurrDate = Format(Now(), "MM/DD/YYYY")
ObjDate = Format(file.DateLastModified, "MM/DD/YYYY")
If CurrDate = ObjDate Then
Cont = Cont + 1
Dim TxtFl, Txt
Set TxtFl = SAPfile.OpenTextFile(RootDir + SAPfile)
Txt = TxtFl.ReadLine
ActiveSheet.Cells(Cont, "A").Value = Txt
ArchTxt.Close
End If
SAPfile = Dir(RootDir)
Loop
End Sub
Try something like this instead, use the command prompt to get an array of files and loop through them using the FSO to check the modified date and read the text into the next blank cell in column A:
Sub SO()
RootDir$ = "\HOME\SAP\dir\"
For Each x In Filter(Split(CreateObject("WScript.Shell").Exec("CMD /C DIR " & RootDir & "*.* /B /A:-D").StdOut.ReadAll, vbCrLf), ".")
With CreateObject("Scripting.FileSystemObject")
If DateValue(.GetFile(RootDir & x).DateLastModified) = Date Then _
Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = .OpenTextFile(RootDir & x, 1).ReadAll
End With
Next x
End Sub