Wilder1626
asked on
Excel to text file
Hello all,
I need your help to modify a macro i have.
The macro will take all columns from the excel sheet and transfer data in a text file based on this part of the code:
But here is my problem.
There is about 25 columns where I have always the same value. All the rest varies and populated by me.
So what i want to do, is to have only 16 columns, and in my macro, extract them to the text file but force some vFieldArray to have specific text.
Ex:
Column A = Test 1
Column B = Test 2
Column C = Test 3
But what i will get has a final result would be:
Array1 = "H"
Array1 = "A"
Array12 = Column A text = Test 1
Array6 = Column B text = Test 2 etc...
Is that possible?
Does it make sense?
Thanks again for your help
Full code
I need your help to modify a macro i have.
The macro will take all columns from the excel sheet and transfer data in a text file based on this part of the code:
vFieldArray = Array(1, 1, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
But here is my problem.
There is about 25 columns where I have always the same value. All the rest varies and populated by me.
So what i want to do, is to have only 16 columns, and in my macro, extract them to the text file but force some vFieldArray to have specific text.
Ex:
Column A = Test 1
Column B = Test 2
Column C = Test 3
But what i will get has a final result would be:
Array1 = "H"
Array1 = "A"
Array12 = Column A text = Test 1
Array6 = Column B text = Test 2 etc...
Is that possible?
Does it make sense?
Thanks again for your help
Full code
Public Sub GenerateFormattedOrderImportFile()
Const DELIMITER As String = "" 'Normally none
Const PAD As String = " " 'or other character
Dim vFieldArray As Variant
Dim myRecord As Range
Dim nFileNum As Long
Dim i As Long
Dim sOut As String
'vFieldArray contains field lengths, in characters, from field 1 to N
vFieldArray = Array(1, 1, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
nFileNum = FreeFile
Open "C:\Documents and Settings\All Users\Desktop\ordtemp." For Output As #nFileNum
For Each myRecord In Range("A11:A" & _
Range("A" & Rows.Count).End(xlUp).Row)
With myRecord
For i = 0 To 41
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & _
String(vFieldArray(i), PAD), vFieldArray(i))
Next i
Print #nFileNum, Mid(sOut, Len(DELIMITER) + 1)
sOut = Empty
For i = 42 To UBound(vFieldArray)
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & _
String(vFieldArray(i), PAD), vFieldArray(i))
Next i
Print #nFileNum, Mid(sOut, Len(DELIMITER) + 1)
sOut = Empty
End With
Next myRecord
Close #nFileNum
' Open our source file
f1 = FreeFile
Open "C:\Documents and Settings\All Users\Desktop\ordtemp." For Input As #f1
' Open our target file
f2 = FreeFile
Open "C:\Documents and Settings\All Users\Desktop\ord.02" For Output As #f2
' Start processing till we reach the end
Do While Not EOF(f1)
' Read a line from the source file
Line Input #f1, x
' And if the line isn't empty, write it to the target file
If x <> " " Then
If x <> " " Then
Print #f2, x
End If
End If
Loop
' Close the two opened files
Close #f2
Close #f1
'Delete the unecessary temp file
strFile = "C:\Documents and Settings\All Users\Desktop\ordtemp."
Set fs = CreateObject("Scripting.FileSystemObject")
fs.deletefile strFile
'This formats name of the text file to be ord.YYYYMMDDHHMI
OldFile1 = "C:\Documents and Settings\All Users\Desktop\ord.02"
newfile1 = Format(Now, "yymmddhhmmss")
newfile1 = OldFile1 & newfile1
Name OldFile1 As newfile1
MsgBox "File Creation Complete"
End Sub
ASKER
You are almost there.
I want to remove in excel some columns where it is always the same value, but still have it in the text file when created.
Ex: "H" and "A" are default value. So i don't what them in the excel file, but when i will create the text file, it will add them in.
I want to remove in excel some columns where it is always the same value, but still have it in the text file when created.
Ex: "H" and "A" are default value. So i don't what them in the excel file, but when i will create the text file, it will add them in.
I'm not entirely sure I got the same from your question as akoster but I *think* what you need to do is add the constants into the 'i' loops where you are building the output string using a case statement:-
For example:
For i = 0 To 41
select Case i
Case 12
sOut = sOut & DELIMITER & "Test1"
Case 6
sOut = sOut & DELIMITER & "Test2"
Case 13,14
sOut = sOut & DELIMITER & "Test3"
Case 21 to 25
sOut = sOut & DELIMITER & "Test4"
Case Else
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & _
String(vFieldArray(i), PAD), vFieldArray(i))
Next i
Perhaps a before and after example (with a smaller array!) would help ?
For example:
For i = 0 To 41
select Case i
Case 12
sOut = sOut & DELIMITER & "Test1"
Case 6
sOut = sOut & DELIMITER & "Test2"
Case 13,14
sOut = sOut & DELIMITER & "Test3"
Case 21 to 25
sOut = sOut & DELIMITER & "Test4"
Case Else
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & _
String(vFieldArray(i), PAD), vFieldArray(i))
Next i
Perhaps a before and after example (with a smaller array!) would help ?
Ah.
do you want to visually get rid of the columns or you want them to be removed ?
if visibility is the problem, the easiest way would be to hide the columns because you then would not have to change the macro.
when you want to remove the columns it might be wise to write out the export functionality like this :
and include the process function
another option (less work when only a small amount of fixed columns involved) is to change the macro to
do you want to visually get rid of the columns or you want them to be removed ?
if visibility is the problem, the easiest way would be to hide the columns because you then would not have to change the macro.
when you want to remove the columns it might be wise to write out the export functionality like this :
for row = 11 to range("A" & rows.count).end(xlup).row
sOut = process(cells(1,1), 1) '-- first entry so no delimiter
sOut = sOut & DELIMITER & process(cells(2,1), 1) '-- second entry, dynamic
sOut = sOut & DELIMITER & process(cells(3,1), 12) '-- dynamic entry
sOut = sOut & DELIMITER & process(cells(4,1), 6) '-- dynamic entry
sOut = sOut & DELIMITER & process(cells(5,1), 6) '-- dynamic entry
sOut = sOut & DELIMITER & process(cells(6,1), 12) '-- dynamic entry
sOut = sOut & DELIMITER & "fixed text" '-- static entry
sOut = sOut & DELIMITER & process(cells(26,1), 11) '-- dynamic entry
[....]
and include the process function
function process(value, size) as string
process = left(value & string(size, " "), size)
end function
another option (less work when only a small amount of fixed columns involved) is to change the macro to
For Each myRecord In Range("A11:A" & _
Range("A" & Rows.Count).End(xlUp).Row)
With myRecord
For i = 0 To 41
select case i
case 5
sOut = sOut & DELIMITER & "fixed text for column 5"
case 12
sOut = sOut & DELIMITER & "fixed text for column 12"
case else
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & String(vFieldArray(i), PAD), vFieldArray(i))
end select
Next i
ASKER
That would be an example of what i need to do.
Excel sheet, you will see the 3 column with data, and the .doc file, just remove the.doc and you will have the text file example.
ord.02111004105914.doc
ex.xlsx
Excel sheet, you will see the 3 column with data, and the .doc file, just remove the.doc and you will have the text file example.
ord.02111004105914.doc
ex.xlsx
ASKER
Hello akoster
From the example you gave me, you have added the H and A in column A and B.
I want to be able to put Test1 in column A and it would still put in the text file HA before the Test1..
From the example you gave me, you have added the H and A in column A and B.
I want to be able to put Test1 in column A and it would still put in the text file HA before the Test1..
my bad, should have directly used the supplied ex.xlsx file to build upon.
Have you checked the ex.xlsm file ?
Have you checked the ex.xlsm file ?
ASKER
yes it is working.
If i need to add more automation like the H and A, but after column C, i'm not to sure how to manage that based on the code:
If i need to add more automation like the H and A, but after column C, i'm not to sure how to manage that based on the code:
Public Sub GenerateFormattedOrderImportFile()
Const DELIMITER As String = "" 'Normally none
Const PAD As String = " " 'or other character
Dim vFieldArray As Variant
Dim myRecord As Range
Dim nFileNum As Long
Dim i As Long
Dim sOut As String
'vFieldArray contains field lengths, in characters, from field 1 to N
vFieldArray = Array(36, 26, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
nFileNum = FreeFile
Open "C:\Documents and Settings\All Users\Desktop\ordtemp." For Output As #nFileNum
'Open "C:\Documents and Settings\All Users\Desktop\temp\ordtemp.txt" For Output As #nFileNum
For Each myRecord In Range("A7:A" & Range("A" & Rows.Count).End(xlUp).Row)
With myRecord
.Select
sOut = "H" & DELIMITER & "A"
For i = 0 To 41
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & String(vFieldArray(i), PAD), vFieldArray(i))
Next i
Print #nFileNum, Mid(sOut, Len(DELIMITER) + 1)
End With
Next myRecord
Close #nFileNum
End Sub
if you want to place 'X' after column C and 'Q' after column E, use :
when you place the additional code below the sout = sout & delimiter & left([...] line, entries will be placed after the indicated column.
when you place the additional code above the sout = sout & delimiter & left([...] line, entries will be placed before the indicated column.
[...]
For i = 0 To 41
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & String(vFieldArray(i), PAD), vFieldArray(i))
'-- column C : i=2
if i = 2 then sOut = sOut & DELIMITER & "X"
if i = 4 then sOut = sOut & DELIMITER & "Q"
Next i
[...]
when you place the additional code below the sout = sout & delimiter & left([...] line, entries will be placed after the indicated column.
when you place the additional code above the sout = sout & delimiter & left([...] line, entries will be placed before the indicated column.
ASKER
Hello akoster
Sorry for the delay,
OK, let me try this. I will give you the feed back.
Thanks again
Sorry for the delay,
OK, let me try this. I will give you the feed back.
Thanks again
no problem !
ASKER
Hello akoster,
It is working. But small question, If for example, after the 3\4 of the excel row that as been transferred in the text file, i need to transfer the last columns in the row just under the first on in the text file, how can i do that:
Ex:
In the excel sheet, this is only 1 row, but in the text file, it is 2, the second, starting with "P".
Is that possible?
It is working. But small question, If for example, after the 3\4 of the excel row that as been transferred in the text file, i need to transfer the last columns in the row just under the first on in the text file, how can i do that:
Ex:
HAMH2440446001WESTOBHOST 24 Example 20100925110020100926170020100925000120100926170024 COL M
P MH2440446001WESTOB100 1100 15
In the excel sheet, this is only 1 row, but in the text file, it is 2, the second, starting with "P".
Is that possible?
ASKER
Ohh that is working like that
For Each myRecord In Range("A7:A" & Range("A" & Rows.Count).End(xlUp).Row)
With myRecord
.Select
sOut = "H" & DELIMITER & "A"
For i = 0 To 4
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & String(vFieldArray(i), PAD), vFieldArray(i))
'-- column C : i=2
If i = 2 Then sOut = sOut & DELIMITER & "H"
If i = 4 Then sOut = sOut & DELIMITER & "A"
If i = 6 Then sOut = sOut & DELIMITER & Format(Now, "yyyymmddhhmmss")
Next i
Print #nFileNum, Mid(sOut, Len(DELIMITER) + 1)
sOut = Empty
sOut = "P" & DELIMITER
For i = 5 To UBound(vFieldArray)
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & _
String(vFieldArray(i), PAD), vFieldArray(i))
Next i
Print #nFileNum, Mid(sOut, Len(DELIMITER) + 1)
sOut = Empty
End With
ASKER
Hello again,
I'm doing lots of test right now and i dont see that it follow these criterias:
The arrays should be where the column data / value starts on the text file.
But is does not if i use :
If i = 0 Then sOut = sOut & DELIMITER & Range("E1").Text should be just after column A, at position 19 on the test file,
and
If i = 1 Then sOut = sOut & DELIMITER & "HOST" should be just after but at position 25 on the text file.
after these 2, then it return to column B of the excel sheet.
but if i remove this conditions, everything is in place, based on Array(36, 26, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
I'm doing lots of test right now and i dont see that it follow these criterias:
vFieldArray = Array(36, 26, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
The arrays should be where the column data / value starts on the text file.
But is does not if i use :
If i = 0 Then sOut = sOut & DELIMITER & Range("E1").Text
If i = 1 Then sOut = sOut & DELIMITER & "HOST"
If i = 0 Then sOut = sOut & DELIMITER & Range("E1").Text should be just after column A, at position 19 on the test file,
and
If i = 1 Then sOut = sOut & DELIMITER & "HOST" should be just after but at position 25 on the text file.
after these 2, then it return to column B of the excel sheet.
but if i remove this conditions, everything is in place, based on Array(36, 26, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
ASKER
In a quick word, all if condition does nor respect the vFieldArray . It just follow right away the column data result.
But if a result from a column is transferred in the text file, the IF condition may not be just right after it.
ex:
column 2 = Test 1
If condition = Test2
The result could be: "Test1 Test 2" and not automatically "Test1Test2"
That is way i need to follow the vFieldArray : (36, 26, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
Does it make sense?
But if a result from a column is transferred in the text file, the IF condition may not be just right after it.
ex:
column 2 = Test 1
If condition = Test2
The result could be: "Test1 Test 2" and not automatically "Test1Test2"
That is way i need to follow the vFieldArray : (36, 26, 12, 6, 6, 12, 12, 11, 3, 12, 12, 12, 12, 12, 1, 20, 12, 1, 1, 3, 1, 12, 20, 11, 20, 7, 20, 11, 1, 12, 12, 12, 12, 1, 20, 12, 12, 12, 1, 50, 12, 75, 1, 1, 12, 6, 6, 9, 6, 6, 12, 5, 35, 1, 50)
Does it make sense?
that is correct. If you want to have the added texts to also follow the vfieldarray text lengths, you can update lines like
to
pay attention though that the use of variable i to link to the 'i' est column in the worksheet requires carefull consideration on the setup of the vFieldArray.
when the i=2 variable inserts contents of cell C2 with length 12 characters, the "H" letter will also have a length of 12 characters.
If i = 2 Then sOut = sOut & DELIMITER & "H"
to
If i = 2 Then sOut = sOut & DELIMITER & Left("H" & String(vFieldArray(i), PAD), vFieldArray(i))
pay attention though that the use of variable i to link to the 'i' est column in the worksheet requires carefull consideration on the setup of the vFieldArray.
when the i=2 variable inserts contents of cell C2 with length 12 characters, the "H" letter will also have a length of 12 characters.
instead it might be a good idea to insert defined texts with hardcoded lengths like this :
[...]
sOut = sOut & DELIMITER & Left(.Offset(0, i).Text & String(vFieldArray(i), PAD), vFieldArray(i))
[...]
If i = 0 Then sOut = sOut & DELIMITER & left(Range("E1").Text & string(10, PAD), 10)
if i = 1 Then sOut = sOut & DELIMITER & left("HOST" & string(20, PAD), 20)
If i = 2 Then sOut = sOut & DELIMITER & Left("H" & String(12, PAD), 12)
[...]
ASKER
Hello akoster
Something is strange here
if i do this:
If i = 0 Then sOut = sOut & DELIMITER & Left(Range("E2").Text & String(16, PAD), 6)
If i = 0 Then sOut = sOut & DELIMITER & Left("HOST" & String(21, PAD), 4)
or
If i = 0 Then sOut = sOut & DELIMITER & Left(Range("E2").Text & String(20, PAD), 6)
If i = 0 Then sOut = sOut & DELIMITER & Left("HOST" & String(28, PAD), 4)
I have the same result.
Question for you, is there a way to use this for everything? even to manage the filed for the column?
If i = 0 Then sOut = sOut & DELIMITER & Left("H" & String(1, PAD), 1)
If i = 1 Then sOut = sOut & DELIMITER & Left("A" & String(2, PAD), 1)
If i = 2 Then sOut = sOut & DELIMITER & Left(COLUMN A.Text & String(3, PAD), 12)
If i = 2 Then sOut = sOut & DELIMITER & Left(Range("E2").Text & String(15, PAD), 6)
If i = 3 Then sOut = sOut & DELIMITER & Left("HOST" & String(22, PAD), 4)
Ex: (0, PAD), 1) = Space 1 on the file, with a length of 1 digit.
(1, PAD), 1) = Space 2 on the file, with a length of 1 digit.
(3, PAD), 12) = Space 3 on the file, with a length of 12 digit......
Something is strange here
if i do this:
If i = 0 Then sOut = sOut & DELIMITER & Left(Range("E2").Text & String(16, PAD), 6)
If i = 0 Then sOut = sOut & DELIMITER & Left("HOST" & String(21, PAD), 4)
or
If i = 0 Then sOut = sOut & DELIMITER & Left(Range("E2").Text & String(20, PAD), 6)
If i = 0 Then sOut = sOut & DELIMITER & Left("HOST" & String(28, PAD), 4)
I have the same result.
Question for you, is there a way to use this for everything? even to manage the filed for the column?
If i = 0 Then sOut = sOut & DELIMITER & Left("H" & String(1, PAD), 1)
If i = 1 Then sOut = sOut & DELIMITER & Left("A" & String(2, PAD), 1)
If i = 2 Then sOut = sOut & DELIMITER & Left(COLUMN A.Text & String(3, PAD), 12)
If i = 2 Then sOut = sOut & DELIMITER & Left(Range("E2").Text & String(15, PAD), 6)
If i = 3 Then sOut = sOut & DELIMITER & Left("HOST" & String(22, PAD), 4)
Ex: (0, PAD), 1) = Space 1 on the file, with a length of 1 digit.
(1, PAD), 1) = Space 2 on the file, with a length of 1 digit.
(3, PAD), 12) = Space 3 on the file, with a length of 12 digit......
this is not strange, it's the way it is supposed to be.
the part after the delimiter consists of two functions :
- left
- string
for simplicity, let's say that E2 contains 'A'
if you say range("E2").text & string(16, "*"); thus command is 'add 16 characters after text in E2'; you will get
[A****************]
if you then use left(range("E2").text & string(16, "*"), 6); thus command is 'take the first 6 characters of this'; you will get
[A*****]
which is the same as saying 'take the first 6 characters of (add 20 characters after text in E2)'
the part after the delimiter consists of two functions :
- left
- string
for simplicity, let's say that E2 contains 'A'
if you say range("E2").text & string(16, "*"); thus command is 'add 16 characters after text in E2'; you will get
[A****************]
if you then use left(range("E2").text & string(16, "*"), 6); thus command is 'take the first 6 characters of this'; you will get
[A*****]
which is the same as saying 'take the first 6 characters of (add 20 characters after text in E2)'
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks,
I will try this and let you know the result.
I will try this and let you know the result.
ASKER
Hello,
Sorry for the delay. Thanks again for your help, now it work.
Sorry for the delay. Thanks again for your help, now it work.
If I get it right you want to minimize the amount of information stored in the text files.
if the columns with fixed data are always the same columns, you could completely take these out of the text file and insert constant values instead.
Otherwise, you could insert a number of definition lines such as e.g.