Export excel to csv-Retain number format to Text - excel

I'm using this code from here to Transposed convert excel to csv file. It's working perfect (Thanks to Nat).
Now I'm facing an issue : as I want to read from this file to fill out Autocad table, I need to csv number format to be as "Text" format(now it's "General" format which is normally happening when it opens with excel). When I import my csv data, it omits leading zero cells and changing 1:100 to 0.01.
When I open csv file with excel and change those cells format to "Text", then save and close file, it's working fine. How can I automate this process (or save with Text format in the first place) as I don't want each user do this manually.
Thanks
Private Sub Exporttocsv()
Dim ColNum As Integer
Dim Line As String
Dim LineValues() As Variant
Dim OutputFileNum As Integer
Dim PathName As String
Dim RowNum As Integer
Dim SheetValues() As Variant
PathName = Application.ActiveWorkbook.Path
OutputFileNum = FreeFile
Open PathName & "\Test.csv" For Output Lock Write As #OutputFileNum
SheetValues = Sheets("Current Revision").Range("B2:CV98").value
Dim RowMax
RowMax = UBound(SheetValues)
Dim ColMax
ColMax = 99
ReDim LineValues(1 To RowMax)
For ColNum = 1 To ColMax
For RowNum = 1 To RowMax
LineValues(RowNum) = SheetValues(RowNum, ColNum)
Next
Line = Join(LineValues, ",")
Print #OutputFileNum, Line
Next
Close OutputFileNum
End Sub

Verify that the CSV contains the values as you want them (e.g. 1:100 instead of 0.01), using any text viewer/editor like notepad, etc.
If values aren't formatted correctly, then to format them as text:
With Sheets("Current Revision").Range("B2:CV98")
.numberformat = "#"
.entirecolumn.autofit 'To avoid #### errors as we're using text property below
SheetValues = .text
End with
The above should replace this line in your original code.
SheetValues = Sheets("Current Revision").Range("B2:CV98").value
The alternative would be to modify the values in the array to, before printing to text file.
Untested and written on mobile, sorry for bad formatting. Hope it works.

For writing the 1:100 ratio as is, into CSV, best is to use the type conversion when you are writing values in to the CSV file. like below :
LineValues(RowNum) = CStr(SheetValues(RowNum, ColNum))
However, if you want leading Zeros, i dont think the type conversion also retains the leading zeros.

Related

extract specific rows of .tbl files in excel

I have an excel file with the following links:
These links are connected to files with the following data:
I want the yellow part of the notepad file to be read into the .xlsx file yellow parts (the notepad is an opened version of the .tbl file). The dotted parts differ for each Version number. (This code is used as a check that the right discount curve is used). However, the discount_curve.tbl format is the only format the next programme used is able to handle. Therefore, it has the same name just in a different folder.
Is there a way excel/vba can read in every third line whilst the file read in depends on the folder link? I strongly prefer to have the whole process automated since there are many many version numbers. Furthermore, I do not want to change the file formatting, since I want the process to be as clean as possible.
Could someone help me out?
Kind regards.
Please, try the next function, if the necessary data to be extracted exists in a single file, at every three rows.. It will return a 2D array able to be dropped at once in the range you need:
Function extractThirdLine(filePath As String) As Variant
Dim arrTxt, i As Long, arrFin, k As Long
'read the file content in an array:
arrTxt = Split(CreateObject("Scripting.FileSystemObject").OpenTextFile(filePath, 1).ReadAll, vbCrLf)
ReDim arrFin(1 To Int(UBound(arrTxt) / 3) + 1, 1 To 1)
For i = 2 To UBound(arrTxt) Step 3 'start from 2, because arrTxt is 1D array
k = k + 1
arrFin(k, 1) = arrTxt(i) 'build the filal array containing the necessary rows
Next i
extractThirdLine = arrFin
End Function
Your picture does not show the rows and columns headers. So, supposing that the range you show us exists in columns "A:C" and you need to place the extracted data in column "D:D", please use the next way:
Sub testExtractThirdLine()
Dim filePath As String, arrVal, el
filePath = "your text file full name" 'please write here the correct file name
arrVal = extractThirdLine(filePath)
Range("D1").Resize(UBound(arrVal), 1).value = arrVal
End Sub
If the range you show is not the one I supposed, you cam easily adapt Range("D1") to the immediately after the columns range and its row to be the first row of the range in discussion.
If something not clear enough, please do not hesitate to ask for clarifications.
Edited:
But if each third line can be found in a file, for each row, and the path to the respective file is obtained by concatenation of the three columns, the next function will do the job:
Function extractLine(filePath As String) As String
extractLine = Split(CreateObject("Scripting.FileSystemObject").OpenTextFile(filePath, 1).ReadAll, vbCrLf)(2)
End Function
It can be called as:
Sub extractStrings()
Dim i As Long, arr, arrFin, lastRow As Long
lastRow = Range("A" & rows.count).End(xlUp).Row 'supposing that 'C:\' exists in A:A column
arr = Range("A2:C" & lastRow).value
ReDim arrFin(1 To UBound(arr), 1 To 1)
For i = 1 To UBound(arr)
arrFin(i, 1) = extractLine(arr(i, 1) & arr(i, 2) & arr(i, 3))
Next i
'drop the processed array content at once:
Range("D2").Resize(UBound(arrFin), 1).value = arrFin
End Sub
Seems like you're looking for common I/O opearations i.e. reading file line by line.
Pretty good example was shown [here][1]
To reach your goal we need to add some if-conditions to extract every third line of your text files.
Modulo division will be a good helper.
For example we have 'i' as row number
then we just need to make an if condition looks smth like that:
If (i mod 3) = 0 Then ...
It means that we're looking for every 'i' which divided by 3 gives us a remainder of 0
This way our code will look something like this
Sub ReadFileLineByLine()
Dim my_file As Integer
Dim text_line As String
Dim file_name As String
Dim i As Integer
file_name = "C:\text_file.txt"
my_file = FreeFile()
Open file_name For Input As my_file
i = 1
While Not EOF(my_file)
Line Input #my_file, text_line
If (i mod 3) = 0 Then
Cells(i, "A").Value = text_line
End If
i = i + 1
Wend
End Sub
[1]: https://excel.officetuts.net/vba/read-a-text-file/#:~:text=Reading%20a%20file%20line%20by%20line,-Let's%20read%20text&text=Open%20VBA%20Edit%20(Alt%20%2B%20F11,and%20insert%20the%20following%20code.&text=First%2C%20a%20new%20file%20is,places%20it%20inside%20a%20worksheet.
You can create a User function that will read the lines from the given file and return the third one.
Here is such a function (Disclaimer: there is no error management in this code it can probably be improved a lot)
Function Get3rdLine(filename As String)
Dim f As Long
f = FreeFile
Open filename For Input As f
Line Input #f, Get3rdLine ' just ignore this line
Line Input #f, Get3rdLine ' and this one too
Line Input #f, Get3rdLine ' and return this one
Close #f
End Function
You can call it with the path of the file you want to read from:
=Get3rdLine(CONCATENATE(A1,B1,C1)) for example if your path is defined by cells A1, B1 and C1.

How from Columns separated dataset, to a comma separated one?

i need to separate the columns of my dataset into comma separated how con I do this? I need a dataset that looks like this:
#VBasic2008 here is what i get in the middle of the sheet: the first and second row are my tries with your function CONCAT. While i need something like the rightest part of the image.... like 6,40,45,52. Not all the values merged..
So i did it using CONCAT function but i had to manually compute that for each column i show how for the ones that eventually will need help (note i used ; instead of , beacause my excel seems not working with ,)
and this is finally the final output
Ok but what if I have a dataset of 1000 columns? This process need to be much much quicker than this. This is not optimized.
I have written several comments on your question which may be hard to follow. So I decided to make a full solution which actually a trick.
Note that Microsoft Excel tries to guess the data structure of the file content if the file is suffixed with .csv (extension). For that reason, whenever you open a .csv file, you get your data in columns instead of a single columns with comma separated values.
In order to achieve what you want, first, save your data as in the comma separated values (.csv) file format.
Then change your file extension from .csv to, i.e. .txt (text file) for example:
if your file name is "data.csv", change it to "data.txt". Please make sure you see the file extension as csv before you change it because in some case you don't see the file extension; therefore when you rename it, it remains a csv file.
Note: If you don't see file extension, if you are on Microsoft Windows, follow this link.
Once you rename the file into txt file format, you can then open it in your Excel application by going to File -> Open -> then browse the txt file.
There you go and get what you one.
You don't need to code or use any functions to achieve that although you can choose to do so if you wish as it is also a good solution.
If you are looking for a formula solution
TEXTJOIN(", ", TRUE, Range)
where Range is the column span of expected values
Option Explicit
Sub CSV()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim LR As Long, xRow As Range
LR = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
For Each xRow In ws.Range("A1:A" & LR)
xRow.Offset(0, 6).Value = WorksheetFunction.TextJoin(", ", True, xRow.Resize(1, 6))
Next xRow
Application.ScreenUpdating = True
End Sub
This is already separated by commas, so you just have to rename it to a .csv file.
in Windows Explorer, go to the ribbon and go to the 'view' tab and enable 'File Name Extensions'.
Navigate to your file, right click and rename it to THEFILENAME.csv instead of THEFILENAME.xlsx
Now when you open this up in excel, it should have the grid.
What is the extension of the file? .xls, .txt or .csv?
If it is in .xls then you can simply open the file in Excel and then use the File->save as menu and then selecting the Comma Separated from the file type drop down.
If file has .csv extension and you are trying to open it in Excel then you will see columns even the file has commas in it. To verify that if the file is comma separated then simply open with notepad or other text editors to see the comma separated values.
If there is any other separator like colon : or other and want to replace with comma then simply use the find and replace option in notepad.
CONCAT Excel UDF
I wrote this a while ago.
In VBE add a module and copy the following code to it.
The Code
'*******************************************************************************
' Purpose: Concatenates the values of cells of a specified range.
' Read only. String.
' Syntax: CONCAT(Range, Separator, Row0Column1)
' Inputs:
' Range A valid range in any open workbook. Required.
' Separator A string to be used as a separator between the values.
' Default is the space character. Optional.
' Row0Column1 If 0 it concatenates by row, if 1 then by column.
' Default is 0. Optional.
' Returns: A string containing all the values of the specified range.
'*******************************************************************************
Function CONCAT(ByVal Range As Range, Optional Separator As String = _
" ", Optional Row0Column1 As Long = 0) As String
'***************************************
' Variables
Dim xdRowStart As Long, xdRowEnd As Long, xdRowCounter As Long
Dim xdColumnStart As Long, xdColumnEnd As Long, _
xdColumnCounter As Long
Dim xdSep As String, xdString As String, xdCheckEmptyString As String
Dim xdWS As Worksheet
'***************************************
' Values
xdString = ""
xdSep = Separator
Set xdWS = Range.Worksheet
xdRowStart = Range.Row
xdRowEnd = xdRowStart + Range.Rows.count - 1
xdColumnStart = Range.Column
xdColumnEnd = xdColumnStart + Range.Columns.count - 1
'***************************************
' Determine concatenated direction: by row or by column
Select Case Row0Column1
Case 0
GoTo ConcatenateByRow
Case 1
GoTo ConcatenateByColumn
Case Else
MsgBox "Row0Column1:" & vbCr _
& "Ommit or use 0 for Concatenating by Row." & vbCr _
& "Use 1 for Concatenating by Column."
GoTo ConcatenateFinal
End Select
'***************************************
' Concatenate by Row:
ConcatenateByRow:
For xdRowCounter = xdRowStart To xdRowEnd
For xdColumnCounter = xdColumnStart To xdColumnEnd
If xdString = "" Then 'xdString is empty; all cells were empty so far
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdCheckEmptyString
End If
Else 'xdString is not empty
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdString & xdSep & xdCheckEmptyString
End If
End If
Next xdColumnCounter
Next xdRowCounter
GoTo ConcatenateFinal
'***************************************
' Concatenate by Column:
ConcatenateByColumn:
For xdColumnCounter = xdColumnStart To xdColumnEnd
For xdRowCounter = xdRowStart To xdRowEnd
If xdString = "" Then 'xdString is empty; all cells were empty so far
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdCheckEmptyString
End If
Else 'xdString is not empty
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdString & xdSep & xdCheckEmptyString
End If
End If
Next xdRowCounter
Next xdColumnCounter
GoTo ConcatenateFinal
'***************************************
ConcatenateFinal:
CONCAT = xdString
End Function
'*******************************************************************************
Usage in Excel
=CONCAT($A1:$G1,",") and copy down:
=CONCAT($A2:$G2,",")

Trouble converting Excel file to .csv

My customer has a file they have used, for some time, to upload data to their application. The field in the Oracle table is VARCHAR 50. The field in the Excel spreadsheet they use is column width 50 and marked as General. I change it to Text and save as .csv. All the rows that have alphanumeric in the field save fine, but the ones that are all numbers convert to scientific notation. I found something on here changing the format (Data > Text to columns) from General to Text. Nothing makes the numbers convert as text like the other values in the field in this spreadsheet. What can I do to ensure it does this every time? They say it is the 1st time they've seen it... I doubt that. Still, I am on the hook to solve the problem. I need to provide them with a solution so that when they send me this data, twice a year, to upload, it works correctly. Any help would be greatly appreciated. Thanx.
Public Sub WritetxtFiles()
Const DELIMITER As String = ","
Dim myRecord As Range
Dim myField As Range
Dim nFileNum As Long
Dim sOut As String
Dim counter As Long
Dim holder As String
Dim theDate As Date
Dim formattedDate As String
Dim dailyDirectory As String
nFileNum = FreeFile
theDate = Now
formattedDate = Format(theDate, "yyyyMMdd")
dailyDirectory = "C:\TEMP\" + formattedDate
If Dir(dailyDirectory, vbDirectory) = vbNullString Then
MkDir (dailyDirectory)
Else
End If
Sheets("orig.txt").Activate ' Adjust to match your sheet name
Open dailyDirectory & "\orig.txt" For Output As #nFileNum ' Adjust to match your desired output
counter = 1
For Each myRecord In Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row)
If Cells(counter, 1) <> "" Then
With myRecord
For Each myField In Range("A" & counter, "F" & counter)
sOut = sOut & DELIMITER & myField.Text
Next myField
Print #nFileNum, Mid(sOut, 2)
sOut = Empty
End With
Else
End If
counter = counter + 1
Next myRecord
Close #nFileNum
end sub
This will create a comma delimited file in your C:\Temp[yyyymmdd]
Well, this is for a gov't customer and they don't allow macros in their Excel files. I was able to save as a 97-2003 workbook, then save as .csv. If I open with Notepad instead of Excel, the .csv file appears correct. If I open it with Excel, it converts. Go figure. Thanx for the help. Wish I could have used it.

How to fix dot as the decimal separator in excel

Got a tiny problem, but I can't get it right. Perhaps someone could help me out. Much appriciated.
my Regional Settings for Decimal Separator is "." (Dot).
i have an excel file, which contains decimals places in some columns. while updating the data in excel template i turned off the usersystem setting then applied DOT as the separator. While converting it to text file it is showing the comma "," as the decimal separator.
I am turning of the the user settings by using below code
With Application
StrDecimal = .DecimalSeparator
StrThousand = .ThousandsSeparator
.DecimalSeparator = "."
.ThousandsSeparator = "'"
.UseSystemSeparators = False
End With
Need to check if the Decimal Separator is not eqaul to "." then we need to force to use "." aS Decimal separator.
Please help how to achieve this by using VBA or by using Datavalidation
Thank you very much in advance!
So you've got your data and are writing it to a textfile. Assuming your data is in an array, I'd loop through the array and convert the data after converting it to a string, like so.
Sub ChangeDecimalSeperator()
Dim vData As Variant, ii As Integer, jj As Integer
vData = ActiveSheet.Range("A1:B2")
For ii = LBound(vData, 1) To UBound(vData, 1)
For jj = LBound(vData) To UBound(vData, 2)
'Only convert if it's a number
If VBA.IsNumeric(vData(ii, jj)) Then
'You can also specify the format using VBA.Format$() here, ie force the decimal places
vData(ii, jj) = ReplaceCharacter(VBA.CStr(vData(ii, jj)), ".", ",")
End If
Next jj
Next ii
'Now output vData to your textfile
End Sub
Function ReplaceCharacter(sForString As String, sReplacingCharacter As String, sWithCharacter As String) As String
Dim sStringPrevious As String
'While there is a character that we still need replacing left, keep going. If we can't find one, we're done
Do
sStringPrevious = sForString
sForString = VBA.Replace(sForString, sReplacingCharacter, sWithCharacter)
Loop Until sStringPrevious = sForString
ReplaceCharacter = sForString
End Function

Excel Macro that loops within cells and writes to new file

I need a macro to get some data from an Excel spreadsheet prior to importing it into MySql linking table.
There is a column of charity names and a column with a list of id's separated by commas (these represent charity types)
To for example
Column A
CharityName1
CharityName2
CharityName3
CharityName4
Column B
100, 101,104
(empty)
104
100,105
I would like this to write a new csv file as follows
1,100
1,101
1,104
3,104
4,100
4,105
Thanks in advance for any help
This code will quickly create a csv file c:\temp\dump.csv with this format
[Updated to handle your format
I note that you may have lost data as Excel has applied scientific notation to your fields. For now I have added an ugly workaround to pad out the 0's. Should B2 be a 30 digit field?]
Sub GetEm()
Dim x()
Dim lngCnt As Long
Dim lngCnt2 As Long
Dim lngE As Long
Dim objFSO As Object
Dim objTF As Object
Dim vArr
Dim vArrElem
Set objFSO = CreateObject("scripting.filesystemobject")
Set objTF = objFSO.createtextfile("c:\temp\dump.csv", 2)
x = Application.Transpose(Range("B1", Cells(Rows.Count, "B").End(xlUp)))
For lngCnt = 1 To UBound(x)
lngE = InStr(x(lngCnt), "E")
If lngE > 0 Then
x(lngCnt) = CStr(Replace(Replace(x(lngCnt), ".", vbNullString), "E+", vbNullString) & Application.Rept("0", Right$(x(lngCnt), 2) - lngE + 1))
End If
If Len(x(lngCnt)) > 0 Then
If Len(x(lngCnt)) Mod 3 = 0 Then
For lngCnt2 = 1 To Len(x(lngCnt)) Step 3
objTF.writeline lngCnt & ",'" & Mid$(x(lngCnt), lngCnt2, 3)
Next
End If
End If
Next
objTF.Close
End Sub
I would iterate through the second column and take the values from each cell into an array, lets call it mainArray. (This iterates rows and cols, be warned: How to iterate through a variable-column-length range in Excel using VBA)
Then I would parse until the delimiting ',' and store them in a an array called cellArray with the first value as the numbered cell they were taken from. Then, replace the original cell value in mainArray with the new cellArray. ( String-Manipulation: Split this String delimited by a - character? )
So cell B1 would become cellArray = { 1, 100, 101, 104 } which would be the first value in mainArray. Do this for each cell in column B for the used range.
Then I would create a new csv ( How to create a separate CSV file from VBA? ) and then input the data into it.
To input the data I would loop through each of my saved arrays and store as CellValue = array[0] + ", " + array[i]
Lastly, I would save my new CSV file.

Resources