From a very large Excel file, We loop and store the values from 3 of the columns into variables( uName(Row), mgrName(Row), title(Row) ). From this excel, we also get the number of rows.
The issue comes when I am trying to use StringBuilder to create a separate .xls file to be used later in the application. The code I have looks like this:
Dim XLstring As System.Text.StringBuilder = New System.Text.StringBuilder
Dim newfile As System.IO.StreamWriter
Dim fileTitle
XLstring.Append("Name,Manager,Title" & vbCrLf)
For X As Integer = 2 To countrows
If X = countrows Then
MsgBox(countrows)
MsgBox(uName(X) & "," & mgrName(X) & "," & title(X))
End If
XLstring.Append(uName(X) & "," & mgrName(X) & "," & title(X) & vbCrLf)
Next
fileTitle = System.DateTime.Now.ToString("yy-MM-dd hh-mm-ss") & ".xls"
filePath2 = "myPath" & fileTitle
newfile = File.CreateText(filePath2)
newfile.WriteLine(XLstring)
This works for the most part. I can see that I am grabbing the correct number of rows as well as the correct information in the last row using MsgBox. When I open the resulting .xls file however, there are entries missing at the end of the file. In addition, if I were to change
XLstring.Append("Name,Manager,Title" & vbCrLf)
to something like
XLstring.Append("Name,Manager" & vbCrLf)
the exact number of characters I removed from the Append line will now successfully appear at the end of the file where the information is missing.
Is there some weird functionality that I am not understanding using these functions? I am completey lost and don't understand this behavior.
You need to close the file when you're done:
newfile.Close()
On a side note, your file is being saved with the XLS extension, but since you are exporting a list of comma-separated values, I would suggest saving in CSV format instead.
Related
In my Windows OS, I set my "Date, time or number formats" with the following separators:
Decimal: ","
Milesimal: "."
List: ";"
In excel, I set in File > Options > Advanced > Use System Separators (ticked)
And when I open my CSV file manually, it goes according to the System Separators (data hidden due to confidential data). In the picture below, each data is in one Column
PROBLEM 1:
But when I asked my VBA macro to Open this CSV file, it totally ignored the System Separators. In the picture below, all data are in the Column A
The command I used in VBA to open the file was:
Workbooks.Open (MacroFile.Range("B" & i).Value & "\" & MacroFile.Range("C" & i).Value), UpdateLinks:=False
Note: It gets the Path + FileName through Cell Content
SOLUTION FOR PROBLEM 1 (credit to #FoxfireAndBurnsAndBurns):
Added property Local:=True to Workbooks.Open (MacroFile.Range("B" & i).Value & "\" & MacroFile.Range("C" & i).Value), UpdateLinks:=False, Local:=True
PROBLEM 2:
When I asked my VBA macro to Close+Save this CSV file, it totally ignored the System Separators. It replaced all the ";" with "," list delimiters
The command I used in VBA to Close+Save the file was:
Workbooks(MacroFile.Range("C" & i).Value).Close SaveChanges:=True
PROBLEM 3:
I've noticed too that when I tried to use the Formula command below, it didn't work, even having Separator as ";"
File_CSV.Range("Z1").Formula = "=SUMIF(F:F;""C"";G:G)"
I had to replace for:
File_CSV.Range("Z1").Formula = "=SUMIF(F:F,""C"",G:G)"
SOLUTION FOR PROBLEM 3 (Credit for TimWilliams):
Used .FormulaLocal in File_CSV.Range("Z1").FormulaLocal = "=SUMIF(F:F;""C"";G:G)"
I'm trying to adapt an Excel form I created that uses drive locations to save copies of the form, to work with SharePoint in a similar manner. Currently, the first macro is set up such that it will search the contents of a particular folder to determine the next available number in the queue (i.e. if 1, 2 and 4 already exist, it will assign 3) and save the sheet as that next available number. When the sheet is complete, the second macro will save the file with a specified name based on data within the sheet, in another specified location (again based on data defined within the sheet). The drive is in the process of being retired in our company and everything moved to Cloud-based storage, so I would like a way to complete the same actions but using SharePoint directories.
The code for the first macro is as follows:
Dim strDir As String
Dim file As Variant
Dim savename As Integer
Dim savename_string As String
strDir = "R:\Queue\"
savename = 1
savename_string = CStr(savename)
file = Dir(strDir)
While (CInt(savename_string) = savename)
If file <> (savename & ".xlsm") Then
If file = "" Then
savename = savename + 1
Else
file = Dir
End If
ElseIf file = (savename & ".xlsm") Then
savename = savename + 1
savename_string = CStr(savename)
file = Dir(strDir)
End If
Wend
ActiveWorkbook.SaveAs ("R:\Queue\" & savename_string & ".xlsm")
And then the code for the second macro is as follows:
Dim answer As Integer
Dim error As Integer
Dim delete As String
answer = MsgBox("Are you sure you want to save sheet & close?", vbYesNo + vbQuestion, "WARNING")
If answer = vbYes Then
'Define PWO, assembly, terminal, strand, and gauge As Strings, and define which cells they are on the sheet
delete = ActiveWorkbook.Name
ActiveWorkbook.SaveAs ("R:\" & terminal & assembly & Space(1) & gauge & strand & Space(1) & PWO & Space(1) & Format(Now(), "MM-DD-YYYY") & ".xlsm")
Kill ("R:\Queue\" & delete)
ActiveWorkbook.Close
Else
Exit Sub
End If
Currently the second macro works correctly when replacing the locations with the SharePoint URL locations, but when doing the same with the first macro, it returns an error message "Bad file name or number" at the line file = Dir(strDir). Can I get this code in working order, or is there a better way I should go about this? Thanks!
Hello Dear StackOverFlowers,
My question may be trival but I'm currently out of option to think of after searching all afternoon
Context: I have a excel worksheet with 120 rows or so that I need to use to create files with.
Data is structured as follow:
The A column contains destination file names
B column has the corresponding data that needsto be written in each file
Giving us the following general layout
data file layout
So, to get data from B column written in each A column named files, I wrote the followin VBScript snippet:
Option Explicit
Sub writeExportedMsgToXML()
' wrote that tiny script not to have to copy pate 117 messages by hand to have ops put them back on Q
Dim currentRow As Integer
' modify to match your data row start and end
For currentRow = 2 To 11
Dim messageID As String
Dim messageitSelf As String
messageID = Trim(ActiveSheet.Range("A" & currentRow))
messageitSelf = ActiveSheet.Range("B" & currentRow)
Dim subDirectory As String
subDirectory = "xmls"
Dim filePath As String
filePath = ActiveWorkbook.Path & "\" & subDirectory & "\" & messageID & ".xml"
MsgBox (messageitSelf) ' for test purpose
Open filePath For Output As #1
Write #1, messageitSelf
Close #1
Next currentRow
End Sub
The script does mostly what it's intended for Except , and this is the source of my question today, it enclose the file content between double quotes as you can see below:
file content enclosed in double quotes
So, in a case where a file named F1.xml should just contain <foo><bar>Baz</bar></foo>
My script transform it as "<foo><bar>Baz</bar></foo>"
What I tried
Replacing file writing part with the following
Dim objStream
Set objStream = CreateObject("ADODB.Stream")
objStream.Charset = "UTF-8"
Dim subDirectory As String
subDirectory = "xmls"
Dim filePath As String
filePath = ActiveWorkbook.Path & "\" & subDirectory & "\" & messageID & ".xml"
objStream.Open
objStream.WriteText messageitSelf
objStream.SaveToFile filePath
objStream.Close
With same outcome
Any clues on what I'm missing/Doing wrong ?
Should I declare messageitSelf as a different type ?
Any help would be appreciated :)
Thank you
Write# statements surround strings with double quotes:
Unlike the Print # statement, the Write # statement inserts commas between items and quotation marks around strings as they are written to the file.
Use Print# instead:
Dim fn As Long
fn = VBA.FreeFile
Open filePath For Output As #fn
Print #fn, messageitSelf
Close #fn
I am trying to use vba to read all text in a text file and display it in an excel message box. the problem I have is whilst this is in effect working, it displays each line of text in a separate message box when instead I want it all in one?
can someone please show me where I am going wrong. thanks
If Range("L" & ActiveCell.Row).Value = "Performance" Then
Dim FilePath As String
Dim strLine As String
FilePath = "\\UKSH000-FILE06\Purchasing\New_Supplier_Set_Ups_&_Audits\ATTACHMENTS\" & Range("C" & ActiveCell.Row).Value & "\performance.txt"
Open FilePath For Input As #1
While EOF(1) = False
'read the next line of data in the text file
Line Input #1, strLine
'print the data in the current row
MsgBox strLine
'increment the row counter
i = i + 1
Wend
Close #1
End If
Within your loop you have to concatenate all the lines a string variable and output the result at the end. It's basically like this:
Dim Total As String
' ...
While EOF(1) = False
'read the next line of data in the text file
Line Input #1, strLine
Total = Total & vbNewLine & strLine
'increment the row counter
i = i + 1
Wend
MsgBox Total
Note: While this solution is working, for large files it may not be very efficient due to the fact that what looks like a concatenation in code, in fact means copying the existing content to a new memory location, and then inserting the new line's string. That is done for every line. So for 1000 lines, the incresingly large total string is copied around 999 times.
You need to accumulate the text in a separate string:
Write Dim strAll As String before the loop.
Replace the MsgBox in the loop with strAll = strAll & strLine.
After the loop, use MsgBox strAll
& is used to join strings in VBA. You could separate the individual lines with a space:
strAll = strAll & " " & strLine.
Or even multi-line
strAll = strAll & vbCrLf & strLine.
where vbCrLf is a VBA constant which means "carriage return followed by line feed". You'll introduce an extra space / line feed at the start of the string but I'll leave that for you to fix!
The title is messy, my apologies. Not sure the best way to word that, so if you a better suggestion, please.
The script I have works, but I'm having trouble keeping the leading zeros. I have tried to insert the .NumberFormat = "#", but I can only do that after I have created the file. I also tried adding the "'" at the leading zero when it puts the text into the file and it does add it, but doesn't apply it. It just keeps the "'" in front of the zero.
Suggestions? Thank you in advance!
Original number: 00099999 ----
Currently adds to file as: 99999 ----
If I add "'", it adds to file as: '00099999
Here's the snippet:
FName = i & "_INPUT" & ".csv"
If FName = False Then
Exit Sub 'user cancelled
End If
FNum = FreeFile
Open FName For Output Access Write As #FNum
For Each ir In range
If ir > 0 Then
strtest = ir
newnum = ExtractNumber(strtest)
End If
S = newnum & Chr(9) 'build each line
S = Left(S, Len(S) - 1) 'remove trailing tab
Print #FNum, S 'print to file
Next ir
Close #FNum
End If
How are you testing the CSV file? If you reopen it in Excel, it will remove the leading zeroes at that point - if you open it in Notepad they should still be there, assuming they were written to the file originally.