Manually Define Fixed Widths in Data File - excel

I have a fixed width data file from a third party that contains 1,000 records. It came with a separate document that displays all available columns, char start char end and char length for each column. It has thousands of columns.
My data file doesn't have data in every row so defining the fixed widths in Excel isn't feasible as I might erroneously skip a column because I can't see that it has data.
Is there a text editor that lets you manually type/define or import widths?

What does this "separate document" look like? Let's say I have a text file with a column of width values to be read that looks something like this:
20
25
30
10
5
23
25
10
23
I can then read the values from this text file into excel, and adjust the column widths of my spreadsheet using the following vba code:
Sub colWidth()
Dim widthArray() As String
Dim myFile, textline As String
Dim x, y As Integer
'example text file containing column widths
myFile = "C:\qqq\qqq\qqq\widths.txt"
'loop through the file and store each column width in an array
Open myFile For Input As #1
x = 1
Do Until EOF(1)
Line Input #1, textline
ReDim Preserve widthArray(1 To x)
widthArray(x) = textline
x = x + 1
Loop
Close #1
'using the array of column widths to adjust columns
For y = 1 To UBound(widthArray)
Columns(y).ColumnWidth = Int(widthArray(y))
Next y
End Sub

Related

How to read multiple text files (with multiple lines of data) into a two dimensional array?

DESCRIPTION:
I have 10 text files. And I want to read them into a two dimensional array. Each file looks like this and the number of lines vary. There are 5 lines in this text file but other text files may have more or less than 5 lines.
No. Location(ft) Mix Near Far Comp. Height(ft) B(in) D(in) Angle(degrees)
1 (0.8127,8.66) 35 MPa true true true 9.17 10 36 0
2 (0.8333,60.67) 35 MPa true true true 9.17 10 36 0
3 (0.8333,80.42) 35 MPa true true true 9.17 10 36 0
4 (14.19,26.22) 35 MPa true true true 9.17 10 24 0
The first dimension of the array will contain each of line the text file. The second dimension of the array will be each text file.
So something like this
Redim TotalArray(1 to 1000, 1 to 10)
1000 is definitely more than the number of lines that I have. 10 is for the 10 text files
FINAL PURPOSE:
The last step would be further split the columns of each text file. In other words, I may need a three dimensional array? However, I am testing the codes for the two dimensional array first. I just state my final purpose in case my approach will be futile and you guys can suggest something better.
My codes are as follows
Sub GetFile()
'Loop through all files in a folder
Dim fileName As String
fileName = Dir("C:\*.txt")
Dim arNames() As String
Dim myCount As Integer
myCount = -1
Do Until fileName = ""
myCount = myCount + 1
ReDim Preserve arNames(myCount)
arNames(myCount) = fileName
fileName = Dir
Loop
' Finish reading file names into arNames.
' This part of the code is successful
Dim TextArray()
Dim x As Double
Dim k As Integer
Dim UBound_arNames As Integer
UBound_arNames = UBound(arNames())
ReDim TotalArray(0 To 1000, 0 To UBound_arNames)
For k = 0 To 2
Open "C:\" & arNames(k) For Input As #1
' Open file.
Do While Not EOF(1) ' Loop until end of file.
ReDim Preserve TextArray(x) ' Preserve the Array
Line Input #1, TextArray(x) ' Read line into variable.
TotalArray(x, k) = TextArray(x)
' The bug is the above line. TextArray(x) works fine but it cannot be
' written to TotalArray(x, k). I need the second dimension k to make
' the second dimension contains the number of text files that I have
' I know the bug is here because MsgBox TextArray(0) works
' but MsgBox TotalArray(0,0) or any other cell prints nothing
x = x + 1 ' increment array count
Loop
Close #1 ' Close file.
MsgBox TextArray(0)
MsgBox TextArray(1)
Next k
End Sub
Please help me
You may be overthinking this and you may be using the wrong tool. This can easily be done with Power Query. Put all files into one folder. Get Power Query to read and append all files. Doesn't matter how many there are in the folder.
In Power Query you can just click through this with ribbon commands. You won't need to write code (although you can get creative with M if you want to). Data > Get Data > From File > From Folder. Take it from there.
When the data in the files changes, or when there are more or fewer files in the folder, just refresh the query.

vba powerpoint formatting % and $ [duplicate]

This question already has answers here:
Stop Excel from automatically converting certain text values to dates
(37 answers)
Closed 6 years ago.
I am having a challenge with how MSOffice deals with number formats.
While I believe this is similar root cause to: Stop Excel from automatically converting certain text values to dates
It is different as this is not a date format and this involves both Excel and PowerPoint with VBA.
I have data that I am pulling out of a dB into CSV files and I am doing a .Replace on certain text markers (e.g. ##ReplaceText##) in a PPT template. (There is a good post on the site on how to do this I can't seem to locate now)
There is one field I need to deal with which is tracking a metric, this field is text in my dB, but it can contain special characters - specifically $ and %.
e.g. I could see the following values in the CSV file:
"increase market share","1234","$10","28%"
I want VBA to treat this all as text, so the % and $ characters are maintained...but... Excel reads the data as a number and keeps the $ or % sign. PowerPoint removes the $ or % sign and converts 28% to 0.28 and $10 to 10.
Per the above question, adding "=""28%""" to the .csv in Excel, will give me that exact literal text in PowerPoint.
Adding a preceding space or ' character works in forcing Excel to read the data as text string. But PowerPoint ignores it and behaves same as above. Eg 28% to 0.28.
I tried using FORMAT as below, but because the data is variable, I don't know which case to apply.
sCurrentText = Format(sCurrentText, "$#")
or
sCurrentText = Format(sCurrentText, "0.0%")
If statements don't work because the $ or % are not present in what VBA sees (e.g the $ or % character is already gone)
If sCurrentText Like "*$*" Then or If sCurrentText Like "*%" Then
So my question is how do I force VBA to take what is in the CSV file as text and ignore processing $ or % as special characters and just maintain them in the CSV?
You didn't specify what exactly you want to do with the data in the CSV file, but I've assumed you're trying to open the file in VBA.
If you are opening the CSV file using OpenText (as below) then Excel will automatically parse the data in the format it sees fit. eg:
Workbooks.OpenText fileName:="directory", DataType:=xlDelimited, Comma:=True
You can use a different method to open the CSV file if you want VBA to handle the data as just text which you can use as you see fit.
Sub OpenCSVFile()
Dim ff As Long, iRow As Long, iCol As Long
Dim FilePath As String
Dim FileBuffer As String 'Entire CSV file as one string
Dim LineSeparatedFile() As String 'Array of data separated into lines
Dim LineData() As String 'Array of comma separated values for that line
ff = FreeFile
Open FilePath For Binary Access Read As #ff
FileBuffer = Space$(LOF(ff))
Get #ff, , FileBuffer
Close #ff
LineSeparatedFile = Split(txtBuffer, vbCrLf)
For iRow = 0 To UBound(LineSeparatedFile)
LineData = Split(LineSeparatedFile(i), ",")
For iCol = 0 To UBound(LineData)
'Code to do something with each entry.
'Eg. print to cell as text
ThisWorkbook.Sheets(1).Cells(iRow + 1, iCol + 1).NumberFormat = "#"
ThisWorkbook.Sheets(1).Cells(iRow + 1, iCol + 1).Value = LineData(iCol)
Next iCol
Next iRow
End Sub

Split Cell by Numbers Within Cell

I have some fields that need to be split up into different cells. They are in the following format:
Numbers on Mission 21 0 21
Numbers on Mission 5 1 6
The desired output would be 4 separate cells. The first would contain the words in the string "Numbers on Mission" and the subsequent cells would have each number, which is determined by a space. So for the first example the numbers to extract would be 21, 0, 21. Each would be in its own cell next to the string value. And for the second: 5, 1, 6.
I tried using a split function but wasn't sure how to target the numbers specifically, and to identify the numbers based on the spaces separating them.
Pertinent to your first case (Numbers on Mission), the simple solution could be as shown below:
Sub SplitCells()
Const RowHeader As String = "Numbers on Mission"
Dim ArrNum As Variant
ArrNum = Split(Replace(Range("A1"), RowHeader, ""), " ")
For i = 1 To UBound(ArrNum)
Cells(1, i + 2) = ArrNum(i)
Next
Cells(1, 2) = RowHeader
End Sub
The same logic is applicable to your second case. Hope this may help.
Unless I'm overlooking something, you may not need VBA at all. Have you tried the "Text to Columns" option? If you select the cell(s) with the information you would like to split up, and go to Data -> Text to Columns. There, you can choose "delimited" and choose a space as a delimiter, which will split your data into multiple cells, split by where the space is.
edit: Just realized that will also split up your string. In that case, when you are in 3rd part of the Text to Columns, choose a destaination cell that isn't the cell with your data. (I.E. if your data is in A1, choose B1 as destination, and it'll put the split info there. Then just combine the text columns with something like =B1&" "&C1&" "&D1)
I was able to properly split the values using the following:
If i.Value Like "*on Mission*" Then
x = Split(i, " ")
For y = 0 To UBound(x)
i.Offset(0, y + 1).Value = x(y)
Next y
End If

Extract same column from multiple excel files using xlsread

I have a directory on C drive containing a number of excel files of the same format. I would like to copy column H from each file into a new file using the following script I found online:
dirs=dir('C:\xxx\*.xlsx');
dircell=struct2cell(dirs);
filenames=dircell(1,:);
range = 'H:H';
n = (numel(filenames));
for i = 1:n;
Newfile(:,i) = xlsread(filenames{i},range);
end
This gives an error message of "Subscripted assignment dimension mismatch." with only one column extracted in the resulting file (Newfile).
I played around with the range and noticed that error occurs when xlsread reaches the end of the list of the first file and stops when the value is empty. My column H's have different number of filled values (i.e. file 1 has 20, file 2 has 100, file 3 has 3, etc.).
So, my question is whether it is possible to modify this script so that when it encounters an empty cell, either an empty cell or a NaN cell is extracted and most importantly that it will move on to the next column.
Thank you so much for your help in advance!
Not having Matlab at home I have to take it from the top of my head.
Since the column you read, H, has different number of valid entries you should not try to force them into the resulting array NewFile directly but rather use a temporary variable
dirs=dir('C:\xxx\*.xlsx');
dircell=struct2cell(dirs);
filenames=dircell(1,:);
range = 'H:H';
n = numel(filenames);
Newfile = NaN*ones(1, n);
for nf = 1:n;
tempVar = xlsread(filenames{nf},range);
r = size(NewFile,1); % get number of rows in NewFile
if length(tempVar) > r
% Make Newfile big enough to fit column nf
Newfile = [Newfile;NaN*ones(length(tempVar)-r,n)];
end
Newfile(:,nf) = tempVar;
end

Using VBA, how can I select every other cell in a row range (to be copied and pasted vertically)?

I have a 2200+ page text file. It is delivered from a customer through a data exchange to us with asterisks to separate values and tildes (~) to denote the end of a row. The file is sent to me as a text file in Word. Most rows are split in two (1 row covers a full line and part of a second line). I transfer segments (10 page chunks) of it at a time into Excel where, unfortunately, any zeroes that occur at the end of a row get discarded in the "text to columns" procedure. So, I eyeball every "long" row to insure that zeroes were not lost and manually re-enter any that were.
Here is a small bit of sample data:
SDQ EA 92 1551 378 1601 151 1603 157 1604 83
The "SDQ, EA, and 92" are irrelevant (artifacts of data transmission). I want to use Excel and/or VBA to select 1551, 1601, 1603, and 1604 (these are store numbers) so that I can copy those values, and transpose paste them vertically. I will then go back and copy 378, 151, 157, and 83 (sales values) so that I can transpose paste them next to the store numbers. The next two rows of data contain the same store numbers but give the corresponding dollar values. I will only need to copy the dollar values so they can be transpose pasted vertically next to unit values (e.g. 378, 151, 157, and 83).
Just being able to put my cursor on the first cell of interest in the row and run a macro to copy every other cell would speed up my work tremendously. I have tried using ActiveCell and Offset references to select a range to copy, but have not been successful. Does any have any suggestions for me? Thanks in advance for the help.
It's hard to give a complete answer without more information about the file.
I think if your input data is 2200+ pages long, it's unlikely that opening it with the default excel opening functions is the way to go. Especially since Excel has maximum number of rows and columns. If the file is a text file (.txt) I would suggest opening it with VBA and reading each line, one at a time, and processing the data.
Here's an example to get you started. Just keep in mind that this is transposing each row of text into columns of data, so you will quickly fill all the columns of excel long before you run thru 2200 pages of text. But it's just an example.
Sub getData()
dFile = FreeFile
sFile = "c:\code\test.txt"
Open sFile For Input As #dFile
c = 1
'keep doing this until end of file
Do While Not EOF(dFile)
'read line into dataLine
Input #dFile, dataLine
' break up line into words based on spaces
j = Split(dataLine, " ")
jLength = UBound(j)
If jLength > 2 Then
r = 1
'ignore first 3 words
'and get every other word
'transpose rows of text into columns
For word = 3 To jLength Step 2
Cells(r, c) = j(word)
r = r + 1
Next word
End If
c = c + 1
Loop
Close #Data
End Sub

Resources