I am creating a script to split csv files up, I want to let the user input the interval in which the files are split into new ones.
The problem I am having is that when I input the interval it isn't splitting, but yet if I hard code the value in it does split.
Option Explicit
Const ForReading = 1
Const ForWriting = 2
Dim objFSO, objInputFile, objOutputFile
Dim intLine, intFile
Dim strHeaders
Dim strInputFile, strOutputPrefix, strLine
Dim MyDate
Dim userSplit
Dim split
'strInputFile = InputBox("Enter file location")
strInputFile = "H:\VBS\domS_CUST.csv"
strOutputPrefix = strInputFile & DatePart("yyyy", Now) & "-" & DatePart("m", Now) & "-" & DatePart("d", Now)
intFile = 1
intLine = 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFSO.OpenTextFile(strInputFile, ForReading)
If (objInputFile.AtEndOfStream = True) Then
' The file is empty
WScript.Quit 1
End If
strHeaders = objInputFile.ReadLine
userSplit = InputBox("Enter when you want to split")
Do While (objInputFile.AtEndOfStream = False)
split = userSplit
strLine = objInputFile.ReadLine
If (intLine <= 0) Then
Set objOutputFile = objFSO.CreateTextFile(strOutputPrefix & "_" & intFile & ".csv", True)
objOutputFile.WriteLine strHeaders
intLine = 1
End If
objOutputFile.WriteLine strLine
If (intLine >= split) Then
objOutputFile.Close
Set objOutputFile = Nothing
intFile = intFile + 1
intLine = 0
Else
intLine = intLine + 1
End If
Loop
The input is this line:
userSplit = InputBox("Enter when you want to split")
And I cannot seem to get it to split at the value of this, any help would be much appreciated!
You have an On Error Resume Next in your code that you didn't show, otherwise the line
split = userSplit
would've raised the error
Illegal Assignment: 'split'
split is the name of a built-in function, so it cannot be used as a variable name. It's also completely unnecessary, because you could simply use userSplit without assigning its value to another variable.
Correction: As Ekkehard.Horner pointed out in the comments, the Dim split supersedes the built-in function definition, thus no error is raised.
However, the main reason why your code doesn't work as you expect is that the InputBox function returns a string value. To make the comparison with intLine work correctly, you need to convert the string to an integer or long integer:
userSplit = CLng(InputBox("Enter when you want to split"))
...
If (intLine >= userSplit) Then
And you should at least add a check to handle situations where the user pressed "Cancel":
userSplit = CLng(InputBox("Enter when you want to split"))
If userSplit <= 0 Then WScript.Quit 1
Also, by using the the Line property, your code could be simplified to this:
filename = "H:\VBS\domS_CUST.csv"
Set fso = CreateObject("Scripting.FileSystemObject")
Set infile = fso.OpenTextFile(filename)
prefix = fso.BuildPath(fso.GetParentFolderName(filename) _
, fso.GetBaseName(filename) & "_" & Year(Now) & "-" _
& Right("0" & Month(Now), 2) & "-" & Right("0" & Day(Now), 2) & "_")
userSplit = CLng(InputBox("Enter when you want to split"))
If userSplit <= 0 Then WScript.Quit 1
Do Until infile.AtEndOfStream
If infile.Line = 1 Then
headers = infile.ReadLine
Else
If (infile.Line - 2) Mod userSplit = 0 Then
If infile.Line > 2 Then outfile.Close
Set outfile = fso.CreateTextFile _
(prefix & (infile.Line - 2) \ userSplit + 1 & ".csv", True)
outfile.WriteLine headers
End If
outfile.WriteLine infile.ReadLine
End If
Loop
outfile.Close
Related
So I managed to create a code to copy and paste listbox values to a newly created excel file.
The thing is, I have it all concatenated and separated by a comma. It works fine but because of how it is exported, then I have to use Excel text to columns functionality to put the data like I want.
Here's the code:
Private Sub button_Export_AMAT_Click()
Dim i As Integer
Dim n As Integer
Dim strLine As String
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.CreateTextFile("\\yvavm301\Commun\CF_GDC\base de dados a trabalhar\AM_AT.csv", True)
For i = 0 To Me.List_AM_AT.ListCount - 1
For n = 0 To Me.List_AM_AT.ColumnCount - 1
strLine = strLine & """" & Me.List_AM_AT.Column(n, i) & ""","
Next n
strLine = Left(strLine, Len(strLine) - 1)
a.writeline (strLine)
strLine = ""
Next i
MsgBox "Your file is exported"
End Sub
My question is: is it possible to export a like for like table, ie. having the same number of columns and having them populated with right values?
The change has to be made here (see below), right?
strLine = strLine & """" & Me.List_AM_AT.Column(n, i) & ""","
a.writeline (strLine)
I've tried without luck the following:
strLine = Me.List_AM_AT.Column(n, i)
a.cells(i,n).writeline (strLine)
Does anyone have an idea of what to do?
As said in my comment you could create an Excel file in your code and write the values to that file. Right now you create a text file with your code which leads to the issues you describe in your post (text assistant etc.)
Private Sub button_Export_AMAT_Click()
Dim i As Integer
Dim n As Integer
' You might need to add a reference to Excel if your host application is Access
' Extra/Reference and select Microsoft Excel Object Library
Dim xl As Excel.Application
Set xl = New Excel.Application
Dim wkb As Workbook
Set wkb = xl.Workbooks.Add
Dim wks As Worksheet
Set wks = wkb.Sheets(1)
'Dim strLine As String
'Set fs = CreateObject("Scripting.FileSystemObject")
'Set a = fs.CreateTextFile("\\yvavm301\Commun\CF_GDC\base de dados a trabalhar\AM_AT.csv", True)
For i = 0 To Me.List_AM_AT.ListCount - 1
For n = 0 To Me.List_AM_AT.ColumnCount - 1
wks.Cells(i + 1, n + 1).Value = Me.List_AM_AT.Column(n, i)
'strLine = strLine & """" & Me.List_AM_AT.Column(n, i) & ""","
Next n
'
' strLine = Left(strLine, Len(strLine) - 1)
' a.writeline (strLine)
' strLine = ""
Next i
wkb.SaveAs "D:\TMP\EXPORT.XLSX" ' Adjust accordingly
wkb.Close False
xl.Quit
MsgBox "Your file is exported"
End Sub
I'm reading an XML file in VBA and then using that to extract some information to create another Output XML file. I only need to generate amn output file when the fields in the initial XML file are filled in.
Currently when it gets to an empty tag it fails. I've tried some of the empty array solutions I've found on here but they don't seem to work. Is my code that bad??
Private Sub gDialer()
For i = 7 To 30000
If Sheets("Latest Report").Cells(i, "AL").Value = "Active - G to sign" Then
If Sheets("Latest Report").Cells(i, "AJ").Value <> "" Then
GenerateReadXML "Z:\AReports\A\Reports\readXML\gRead" & i & ".xml", Sheets("Latest Report").Cells(i, "AJ").Value
sendXML "readXML\gRead" & i & ".xml", "gRead" & i & "response", "Read"
Set oXMLFile = CreateObject("Microsoft.XMLDOM")
XMLFileName = "Z:\AReports\A\Reports\fActivities\results\gRead" & i & "response.xml"
'MsgBox XMLFileName
oXMLFile.Load (XMLFileName)
Set Numnode = oXMLFile.SelectNodes("/result/data29/text()")
Set titleNode = oXMLFile.SelectNodes("/result/data25/text()")
Set firstNode = oXMLFile.SelectNodes("/result/data26/text()")
Set lastNode = oXMLFile.SelectNodes("/result/data27/text()")
On Error GoTo didntfindit
Dim numStr As String
Dim titleStr As String
Dim firstStr As String
Dim lastStr As String
'### here's where it fails ###
numStr = Numnode(0).NodeValue
titleStr = titleNode(0).NodeValue
firstStr = firstNode(0).NodeValue
lastStr = lastNode(0).NodeValue
GenerateDialerXML "Z:\AReports\A\Reports\dialerXML\dialer" & i & ".xml", Numnode(0).NodeValue, titleNode(0).NodeValue, firstNode(0).NodeValue, lastNode(0).NodeValue, Sheets("Latest Report").Cells(i, "AJ").Value, 87
sendDialerXML "dialer" & i & ".xml", sendHandshake, "gDResponse"
didntfindit:
End If
End If
Next i
End Sub
When it fails, it's because the XML is like this:
<data24>something</data24>
</data25>
</data26>
</data27>
<data28>something else</data28>
</data29>
It works fine when there are values, but I can't figure out the next step.
Thanks in advance!
I've fixed it now, here's what I came up with, hope this helps someone one day:
oXMLFile.Load (XMLFileName)
Set numNode = oXMLFile.getElementsByTagName("data29")
Set titleNode = oXMLFile.getElementsByTagName("data25")
Set firstNode = oXMLFile.getElementsByTagName("data26")
Set lastNode = oXMLFile.getElementsByTagName("data27")
On Error GoTo didntfindit
Dim numStr As String
Dim titleStr As String
Dim firstStr As String
Dim lastStr As String
numStr = numNode(0).Text
titleStr = titleNode(0).Text
firstStr = firstNode(0).Text
lastStr = lastNode(0).Text
background
I have to create a code in Excel VBA which opens a text file and writes a specific part of some of its strings beginning with ":60F" into a specific cell of the Excel sheet.
This part of the code already works.
issue
However, I´m struggling with the second part of the task. I have to write into another cell of the Excel document a part of a specific string beginning with ":61:".
The problem is, that there are many strings in the text file beginning with "61:", but I need the one which occurs right after the string beginning with "60F:".
I would be extremely grateful if you could help me with this. Thank you very much in advance!
Kind regards
Here is the code I wrote so far:
code
Function extract_opening_balance(ByVal filename As String, subfield_61 As String) As String
Dim i As Integer
Dim pos1 As Integer
strPath = ActiveWorkbook.Path & "\Data of Reporting Month\"
filename = strPath & "MT940_T2_" & main_menu.cbo_Year & Left(main_menu.cbo_Month, 2) & Format(day(CDate(Right(main_menu.lst_Date.List(i), 10))), "00") & ".txt"
Open filename For Input As #1
For i = 3 To 13
Do Until EOF(1)
Line Input #1, textline
If InStr(textline, ":60F:") > 0 Then
If InStr(textline, "EUR") = 13 And InStr(textline, 0) <> 16 Then
'For j = 1 To String(":60F:").Count
pos1 = InStr(subfield_61, "//") + 30
'time_str = Mid(subfield_61, pos1, 6)
'time_str = Mid(time_str, 1, 2) & ":" & Mid(time_str, 3, 2) & ":" & Mid(time_str, 5, 2)
Sheets("op_balance").Range("B" & i).Value = Mid(textline, 6, 1)
Sheets("op_balance").Range("C" & i).Value = Mid(textline, 16, 20)
Sheets("op_balance").Range("D" & i).Value = subfield_61
Sheets("op_balance").Range("E" & i).FormulaR1C1 = "=IF(RC[-3]=""D"",(-1)*RC[-2],RC[-2])"
'Next j
End If
End If
Loop
Next i
End Function
A Regexp option:
random stuff
random guy
Stuff :60F:stuff
other stuff 61:getme
60F more
returns alphanumerics after 61: (preceded by :60F:), ie getme in this example
Sub GetMe()
Dim FSO As Object
Dim FH As Object
Dim objRegex As Object
Dim objRegexMC As Object
Dim strIn As String
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FH = FSO.OpenTextFile("c:\temp\test.txt")
Set objRegex = CreateObject("vbscript.regexp")
strIn = FH.readall
strIn = Replace(strIn, vbNewLine, Chr(32))
With objRegex
.Pattern = ":60F.*61:(\w+)"
If .Test(strIn) Then
Set objRegexMC = .Execute(strIn)
MsgBox objRegexMC(0).submatches(0)
Else
MsgBox "text not found"
End If
End With
End Sub
I am fairly new to vba but have developed a code to use in excel to move text/numbers to a txt file. My issue is I currently have three functions that need to go to the same txt file. When I run it currently the first function has
Set fs = CreateObject("scripting.FileSystemObject")
Set a = fs.createTextFile(Module1.NYS45Uploadfilename, True)
a.writeline (str)
a.Close.
The other two functions had save.
Set fs = CreateObject("scripting.FileSystemObject")
Set a = fs.saveTextFile(Module1.NYS45Uploadfilename, True)
a.writeline (str)
a.Close.
The first function will go to the txt file, the other two I get an error
Object doesn't support this property or method.
When I changed all three to create the last function goes to the txt file. I can not figure out what word to use in order to make the other two functions follow into the txt file in the order they are keyed.
The entire code is as follows
Private Sub addRecord_Click()
On Error GoTo ErrHandler
Module1.NYS45Uploadfilename = Application.GetSaveAsFilename(FileFilter:="Textfiles (*.txt), *.txt")
If Module1.NYS45Uploadfilename = "False" Then Exit Sub
Header_Rec
Detail_Rec1
Detail_Rec2
Dim strmsg As String
strmsg = "Your file has been added here: " & Module1.NYS45Uploadfilename
MsgBox strmsg
Exit Sub
ErrHandler:
MsgBox Err.Number & vbNewLine & Err.Description
Resume Next
End Sub
Function Header_Rec()
Dim str, strfilename, txtpath As String
Dim strlencount, strspacer As Integer
str = str & Range("a3").Value
str = str & Range("b3").Value
str = str & Trim(Range("c3").Value)
strlencount = Len(Trim(Range("c3").Value))
strspacer = 30 - strlencount
str = Module1.SpaceAdd(str, strspacer)
str = str & Range("d3").Value
str = str & Range("E3").Value
str = Module1.SpaceAdd(str, 159)
' Debug.Print Len(str)
Set fs = CreateObject("scripting.FileSystemObject")
Set a = fs.createTextFile(Module1.NYS45Uploadfilename, True)
a.writeline (str)
a.Close
' Debug.Print str
End Function
Function Detail_Rec1()
Dim str, strnum, str2, strfilename, txtpath As String
Dim strlencount, strspacer As Integer
If Range("a7").Value <> "5" Then
Exit Function
End If
str = str & Range("a7").Value
str = str & Range("b7").Value
str = str & Range("c7").Value
str = Module1.SpaceAdd(str, 1)
str = str & Trim(Range("d7").Value)
strlencount = Len(Trim(Range("d7").Value))
strspacer = 30 - strlencount
str = Module1.SpaceAdd(str, strspacer)
str = str & Range("E7").Value
' Debug.Print Len(str)
Set fs = CreateObject("scripting.FileSystemObject")
Set a = fs.addTextFile(Module1.NYS45Uploadfilename, True)
a.writeline (str)
a.Close
' Debug.Print str
End Function
Function Detail_Rec2()
Dim str, strnum, str2, strfilename, strnew, txtpath As String
Dim strlencount, strspacer As Integer
If Range("a11").Value <> "6" Then
Exit Function
End If
str = str & Range("a11").Value
str = str & Range("b11").Value
str = str & Trim(Range("c11").Value)
strlencount = Len(Trim(Range("c11").Value))
strspacer = 11 - strlencount
str = Module1.SpaceAdd(str, strspacer)
strspacer = 30 - strlencount
str = Module1.SpaceAdd(str, strspacer)
str = str & Range("f11").Value
str = str & Range("g11").Value
' Debug.Print Len(str)
Set fs = CreateObject("scripting.FileSystemObject")
Set a = fs.getTextFile(Module1.NYS45Uploadfilename, True)
a.writeline (str)
a.Close
' Debug.Print str
End Function
Consider the below example showing how to write text to the file using OpenTextFile method:
Sub Test()
Const ForWriting = 2
Const ForAppending = 8
Const FormatDefault = -2
Const FormatUnicode = -1
Const FormatASCII = 0
strFile = "C:\TestFile.txt"
strText = "New Unicode text file created, this is the first line." & vbCrLf
WriteTextFile strFile, strText, ForWriting, FormatUnicode
strText = "New line added, this is the second line." & vbCrLf
WriteTextFile strFile, strText, ForAppending, FormatUnicode
strText = "One more line." & vbCrLf
WriteTextFile strFile, strText, ForAppending, FormatUnicode
End Sub
Sub WriteTextFile(strPath, strContent, lngMode, lngFormat)
' strPath: path to the text file
' strContent: text to be written to the file
' lngMode: 2 - For Writing, 8 - For Appending
' lngFormat: -2 - System default, -1 - Unicode, 0 - ASCII
With CreateObject("Scripting.FileSystemObject").OpenTextFile(strPath, lngMode, True, lngFormat)
.Write strContent
.Close
End With
End Sub
I have made a script that allows the user to open a file using the shell browser and once selected they are prompted to enter the interval in which they want to split the .CSV file down into smaller files.
The problem that arises is that once I select the file using the browser I get an unspecified error with the code 80004005 it appears on line 15 character 1 and I have no idea how to solve this.
Any help would be much appreciated!
Option Explicit
Const ForReading = 1
Const ForWriting = 2
Dim objFSO, objInputFile, objOutputFile
Dim intLine, intFile
Dim strHeaders
Dim strInputFile, strOutputPrefix, strLine
Dim MyDate
Dim shell
Dim file
Set shell = CreateObject("Shell.Application")
Set file = shell.BrowseForFolder(0, "Choose a file:", &H4000)
BrowseForFile = file.self.Path
strInputFile = BrowseForFile
strOutputPrefix = objFSO.GetBaseName(strInputFile) & DatePart("yyyy", Now) & "-" & DatePart("m", Now) & "-" & DatePart("d", Now)
userSplit = InputBox("Enter when you want to split")
intFile = 1
intLine = 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFSO.OpenTextFile(strInputFile, ForReading)
If (objInputFile.AtEndOfStream = True) Then
' The file is empty
WScript.Quit 1
End If
strHeaders = objInputFile.ReadLine
Do While (objInputFile.AtEndOfStream = False)
strLine = objInputFile.ReadLine
If (intLine <= 0) Then
Set objOutputFile = objFSO.CreateTextFile(strOutputPrefix & "_" & intFile & ".csv", True)
objOutputFile.WriteLine strHeaders
intLine = 1
End If
objOutputFile.WriteLine strLine
If (intLine >= userSplit) Then
objOutputFile.Close
Set objOutputFile = Nothing
intFile = intFile + 1
intLine = 0
Else
intLine = intLine + 1
End If
Loop
Your BrowseForFolder call misses the third/option parameter; so change
Set file = shell.BrowseForFolder(0, "Choose a file:", &H4000)
to
Set file = shell.BrowseForFolder(0, "Choose a file:", 0, &H4000)
The above (kept for context for comments) is all wrong
The docs state clearly:
Creates a dialog box that enables the user to select a folder and then
returns the selected folder's Folder object.
so you can display the files, but not pick/return them.