Transpose irregular data from .txt import to a table in Excel - excel

I have imported a bunch of data from tables in Word -> .txt -> Excel, but in the conversion to .txt the format of the table is lost and I am now trying to recover it in Excel.
I would just make a simple Copy/Paste Macro based on the Cell Range, but the cell ranges are not the same across each imported .txt file so this won't work as the same data could be in A8 in one sheet then A10 in another.
You could almost move every other row into column B, but the "Date Due" field throws it out of sync.
I want to transpose the copied date into a more functional table format - see picture for example - which I can then analyze. I need to do this for hundreds of sheets but I'm hoping that if I can get it working for one then I can adapt it to work across many.
Each sheet may have multiple products, each new product is preceded by an integer (e.g. 1. Product1; 2. Product2 etc...)
deleted old code that I'd tried to do
EDIT2:
screenshot of typical notepad file
There is a load of text above this, but the first product always starts with QUOTATION MACHINE SCHEDULE, then 1. xxx
EDIT3:
Tried to add in the column I to have Quote Ref: and find this in the text file, but it didn't work. Code change from CDP1802 current solution below
'results sheet
Set ws = ThisWorkbook.Sheets("Results")
ws.Range("A1:I1") = Array("Item", "Date Due", "Type", "Serial Number", "Standard", "Mode", "Range", "Location", "Quote Ref:")
r = 1 ' output row
Select Case s
' match word to set column
Case "type": c = 3
Case "serial number": c = 4
Case "standard": c = 5
Case "mode": c = 6
Case "range": c = 7
Case "location": c = 8
Case "Quote Ref:": c = 9
Case Else: c = 0
End Select
New Screenshot for Quote Ref:

Read the text file into an array and then scan for key words using Select Case. Reading the data into an array allows you to select the value from the row below the key word.
update - Quote Ref added
Option Explicit
Sub ProcessTextFiles1()
Const FOLDER = "C:\temp\SO\Data\" ' folder where the text files are
Dim ws As Worksheet, sFilename As String, sQuoteRef As String
Dim n As Integer, i As Long, r As Long, c As Long
Dim fso As Object, ts As Object, ar() As String, s As String
Set fso = CreateObject("Scripting.FileSystemObject")
' results sheet
Set ws = ThisWorkbook.Sheets("Results")
ws.Range("A1:I1") = Array("Item", "Date Due", "Type", "Serial Number", _
"Standard", "Mode", "Range", "Location", "Quote Ref")
r = 1 ' output row
' scan each file in folder
sFilename = Dir(FOLDER & "*.txt")
Do While Len(sFilename) > 0
n = n + 1
sQuoteRef = ""
' open file and read into array
Set ts = fso.OpenTextFile(FOLDER & sFilename)
s = ts.readAll
s = Replace(s, vbLf, "")
ar = Split(s, vbCr)
ts.Close
'MsgBox sFilename & "=" & UBound(ar)
' parse the strings in the array
i = 0
Do While i <= UBound(ar)
s = LCase(Trim(ar(i)))
'Debug.Print s
If Len(s) > 0 Then ' skip blanks
If Left(s, 10) = "quote ref:" Then
sQuoteRef = ar(i + 1)
End If
If Left(s, 2) Like "#." Or Left(s, 3) Like "##." Then
' new product
r = r + 1
ws.Cells(r, 1) = ar(i)
ws.Cells(r, 9) = sQuoteRef
Else
Select Case s
' match word to set column
Case "type": c = 3
Case "serial number": c = 4
Case "standard": c = 5
Case "mode": c = 6
Case "range": c = 7
Case "location": c = 8
Case Else: c = 0
End Select
' take value below
If c = 4 Then
ws.Cells(r, 4) = ar(i + 1)
ws.Cells(r, 2) = ar(i + 2) ' due date
i = i + 2
ElseIf c > 1 Then
ws.Cells(r, c) = ar(i + 1)
i = i + 1
End If
End If
End If
i = i + 1
Loop
sFilename = Dir
Loop
MsgBox n & " Files processed", vbInformation
End Sub

Related

VBA: Multi-select Listbox to a single cell but without duplicates

I haven't used VBA in about 10 years until needing it this week, so my recall is not that great right now - appreciate any advice you are able to give!
I have a User form where there is a multiple selection listbox option that inserts the selected items into a single cell separated by a comma. The list referenced for the listbox has 2 columns - a GROUP and a PROJECT name.
Multiple projects can fall under the same group. I have the group column going to one cell and the project to another, but if users multi-select projects from the same group they will get the same group name repeated.
How can I adjust this to allow the group name to only appear once in a cell?
Adding grouping to Excel sheet:
For X = 0 To Me.listbox_group.ListCount - 1
If Me.listbox_group.Selected(x) Then
If varGroup = "" Then
varGroup = Me.listbox_group.List (x,0)
Else
varGroup = varGroup & ", " & Me.listbox_group.List(x,0)
End If
End If
Next x
Specifying cell location for the selection to go to:
Sheets("Data").Range("Data_Start").Offset(TargetRow, 0).Value = UCase(varGroup)
In order to get only unique values you could use a dictionary
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
For x = 0 To Me.listbox_group.ListCount - 1
If Me.listbox_group.Selected(x) Then
dict(listbox_group.List(x, 0)) = listbox_group.List(x, 0)
' If varGroup = "" Then
' varGroup = Me.listbox_group.List(x, 0)
' Else
' varGroup = varGroup & ", " & Me.listbox_group.List(x, 0)
' End If
End If
Next x
Dim s As Variant
s = Join(dict.Keys, ",")
Sheets("Data").Range("Data_Start").Offset(TargetRow, 0).Value = UCase(s)
I only assign values because there is a kind of extra feature: If the Key does not exist it automatically adds the Key and Item to the dictionary.
Upper ander lower case pitfall: The above code will a consider groups with the name G1 and g1 as different. If you do not want that use
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
For x = 0 To Me.listbox_group.ListCount - 1
If Me.listbox_group.Selected(x) Then
Dim selElement As String
selElement = UCase(listbox_group.List(x, 0))
dict(selElement) = selElement
' If varGroup = "" Then
' varGroup = Me.listbox_group.List(x, 0)
' Else
' varGroup = varGroup & ", " & Me.listbox_group.List(x, 0)
' End If
End If
Next x
Dim s As Variant
s = Join(dict.Keys, ",")
Sheets("Data").Range("Data_Start").Offset(TargetRow, 0).Value = s

Options for parsing a text file to columns

I am looking for some input and possible example for parsing a text file with the following format: (sorry not sure how to retain the formatting of the file in this text)
NAME ID FORMAT SHORT NAME
DESCRIPTION (this field is on the second row an indented by 5 spaces)
The first row (NAME, ID, FORMAT and SHORT NAME) always consist of just one row. The DESCRIPTION text may span multiple rows. In some cases, there is only a first row of NAME, ID, etc. without a corresponding DESCRIPTION row.
Here is an example of how the data looks in the file now:
NAME ID FORMAT SHORT NAME
DESCRIPTION
ABC 01 xx AB
abcdefg
hijklm
nopqrs
DEF 02 xx DE
abcedfg
hijklmnopqrst
GHI 03 xx.x GH
JKL 001 xx JKL
abcdef
ghijk
lmnopq
rstu
vwxyz
I would like to parse out the NAME, ID, FORMAT, SHORT NAME and DESCRIPTION into 5 separate columns in a csv or excel file for additional analysis. I don't care if the DESCRIPTION field is broken across multiple lines but it can also be concatenated into a single longer string.
Hope this all makes sense. Thanks in advance!
Providing the data for NAME,ID,FORMAT and SHORT NAME is aligned
beneath their header word then use those words on the first line
to calculate the start position and length of each field, then split
the lines into fields using Mid(). Join the description lines and write out to
the previous record before a new record is started. For example
Option Explicit
Sub ParseTextFile()
Const INFILE = "c:\temp\testfile.txt"
Const OUTFILE = "c:\temp\testfile.xlsx"
Dim wbOut As Workbook, ws As Worksheet, iRow As Long
Dim txt As String, ff As Integer, i As Integer, desc As String
Dim start(4) As Integer, length(4) As Integer
Dim count As Integer, msg As String
Set wbOut = Workbooks.Add
Set ws = wbOut.Sheets("Sheet1")
ws.Range("A1:E1") = Array("NAME", "ID", "FORMAT", "SHORT NAME", "DESCRIPTION")
ws.Columns("A:E").NumberFormat = "#"
iRow = 1
ff = FreeFile()
Open INFILE For Input As #ff
While Not EOF(ff)
count = count + 1
Line Input #ff, txt
If count = 1 Then
start(1) = InStr(1, txt, "NAME", vbTextCompare)
start(2) = InStr(1, txt, "ID", vbTextCompare)
start(3) = InStr(1, txt, "FORMAT", vbTextCompare)
start(4) = InStr(1, txt, "SHORT NAME", vbTextCompare)
For i = 1 To 3
length(i) = start(i + 1) - start(i)
Next
Else
If Left(txt, 1) = " " Then
desc = desc & Trim(txt) & " "
Else
' save the description from last record
ws.Cells(iRow, 5) = Trim(desc)
desc = ""
' new row
iRow = iRow + 1
length(4) = Len(txt) - start(4) + 1
For i = 1 To 4
ws.Cells(iRow, i) = Mid(txt, start(i), length(i))
Next
End If
End If
Wend
Close #ff
' final description
ws.Cells(iRow, 5) = Trim(desc)
' save result
ws.Columns("A:E").AutoFit
wbOut.Close True, OUTFILE
msg = count & " lines read from " & INFILE & vbCr & _
iRow - 1 & " rows written to " & OUTFILE
MsgBox msg, vbInformation
End Sub

Extract postal code from address using isNumeric

I want to extract postal code from address. I have tried isNumeric method below to extract 6 numeric from the address. Some of the address got 5 digit and some got 6 digit postal code.
But there is some error where sometimes 11900 only show 1900, 08000 shows 8000, and 4 digit number also show.
Range("A2").Select
i = 2
Do While ActiveCell <> ""
Address = UCase(Trim(Range("C" & CStr(i))) + " " + Trim(Range("D" & CStr(i))) + " " + Trim(Range("E" & CStr(i))) + " " + Trim(Range("F" & CStr(i))))
For p = 1 To Len(Address)
If IsNumeric(Mid(Address , p, 6)) Then
Range("O" & CStr(i)) = Mid(Address, p, 6)
End If
Next p
ActiveCell.Offset(1, 0).Select
i = i + 1
Loop
excel output
Address Postal Code
Wisma Pansar, 23-27 Jln Bengkel P.O. Box 319, 96007 Sibu Sarawak 96007
Wisma Lim , Lot 50A, Sec. 92A, 3.1/2 Sg Besi, 57100 Kuala Lumpur 57100
No. 265A, Jalan Sungai Petani 08300 Gurun Kedah Darul Aman 8300
No. 39, Jalan Nipah, Taman Lip Sin 11900 Sungai Nibong Pulau Pinang 1900
4-G, Lebuh Sungai Pinang 1 Sri Pinang 11600 Jelutong Pulau Pinang 11600
539/2, Gypsum Metropolitan Tower, Rajthevee Bangkok 10400, Thailand 0400,
LOTS 1869 &1938, 18th MILE KAJANG, SEMENYIH ROAD SELANGOR D.E. 1938, *no postal code in address
36a, Joo Chiat Place, Singapore 427760 0
I mean something like this:
Sub test()
Dim c As Range, p As Long, v, addr, i As Long, hit As Boolean
Set c = Range("A2") 'no need to select the cell
Do While c <> ""
addr = c.Value 'using your examples
hit = False
For p = 1 To Len(addr)
'will accept 5 or 6 digits - prefer 6
' so count down...
For i = 6 To 5 Step -1
v = Mid(addr, p, i)
If v Like String(i, "#") Then
c.Offset(0, 1).NumberFormat = "#" 'in case of leading zero
c.Offset(0, 1).Value = v
hit = True
Exit For
End If
Next i
If hit Then Exit For
Next p
Set c = c.Offset(1, 0)
Loop
End Sub
A regular expression approach would probably be much nicer.
To complement #TimWilliams his answer, hereby a solution making use of Array and Regular Expressions (with late binding). So let's immagine the following setup:
Now run the following code:
Sub Test()
Dim lr As Long, x As Long
Dim arr As Variant
Dim RegEx As Object: Set RegEx = CreateObject("vbscript.regexp")
'Set up regular expression
RegEx.Pattern = "\d{5,6}"
RegEx.Global = True
'Go through your data and execute RegEx
With Sheet1 'Change according to your sheets CodeName
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
arr = .Range("A2:A" & lr).Value
.Range("B2:B" & lr).NumberFormat = "#"
For x = LBound(arr) To UBound(arr)
Set Matches = RegEx.Execute(arr(x, 1))
For Each Match In Matches
.Cells(x + 1, 2) = Match.Value
Next Match
Next x
End With
End Sub
Assuming the possibility of multiple matches within a string, the last match will be used.
If you are sure there can only be one match (or none), then you could also use:
If Matches.Count = 1 Then .Cells(x + 1, 2) = Matches.Item(0)
Instead of:
For Each Match In Matches
.Cells(x + 1, 2) = Match.Value
Next Match

Get all columns from Excel except selected

I have excel files converted to txt. In some files, some columns are skipped. That is controlled by database:
file | remove_column
=======+===============
file1 | CASE NOTE
-------+---------------
file2 | Description
-------+---------------
file3 | Item | Address
Remove_Column has the header (1st row). If several columns should be skipped, they are delimited with '|'
I have to compare converted txt file with original excel file if they match. How can I read all columns except those showed in DB table?
I am using UFT 12.5. Reading Excel through Excel.Application or ADO.
Thnx)
UPD: Code I use:
I have columns hard-coded:
Select Case OrigFileName 'file names come from database
Case "Fees mm-yy.xls"
ColumnNames = Split("1,2,3,4,5,6,7,8,9,10,11,12,13", ",")
Case "Exp mm-yy.xls"
ColumnNames = Split("1,2,3,4,5,6,7,8,9,12,13,14,15,16,19,20", ",")
End Select
But there are 50 files, and the business might ask to remove or to add back any columns; also, new files are coming...(((
Dim fsox : Set fsox = CreateObject("Scripting.FileSystemObject")
Dim TargFileRead : Set TargFileRead = fsox.OpenTextFile(targetFile)
Dim OrgExcel : Set OrgExcel = CreateObject("Excel.Application")
OrgExcel.Workbooks.Open(originalfile)
Set vSheet = OrgExcel.WorkSheets(TabUse) 'excel sheet name, comes from database
print vSheet.UsedRange.Rows.Count
For rc = 1 To vSheet.UsedRange.Rows.Count
For coc = 0 To UBound(ColumnNames) 'column names hard-coded
cc = cInt(ColumnNames(coc))
vtext = vSheet.cells(rc,cc)
If NOT(vtext=ChrW(9)) Then
If vstring="" Then
vstring=vtext
Else
vstring = vstring&vbTab&vtext
End If
End If
If len(vstring)>0 Then
TargFileText = TargFileRead.ReadLine
Do
If Left(TargFileText, 1)=ChrW(9) Then
TargFileText = MID(TargFileText, 2)
Else
Exit Do
End If
Loop
Do
If RIGHT(TargFileText, 1)=ChrW(9) Then
TargFileText= mid(TargFileText,1,len(TargFileText)-1)
Else
Exit Do
End If
Loop
TargFileStr = Trim(TargFileText)
If trim(vstring) = trim(TargFileStr) Then
' print "match"
Else
print "-=Not Match=-"&VBNewLine&"txt:::"&trim(TargFileStr)&VBNewLine&"xls:::"&trim(vstring)
End If
End If
Next
I would suggest to replace the Switch statement with a function call that gives you the relevant columns for the sheet as an array. The logic which column is allowed is then put in another function. That should make the logic more flexible than fixed columns.
Function getColumns(OrigFileName as String) As String()
Dim lastCol As Integer
Dim ColumnNumbers As String
lastCol = Sheets(OrigFileName).UsedRange.Columns.Count
For col = 1 To lastCol
If isColumnAllowed(OrigFileName, Sheets(OrigFileName).Cells(1, col)) Then
ColumnNumbers = ColumnNumbers & IIf(Len(ColumnNumbers) = 0, "", ",") & col
End If
Next
getColumns = Split(ColumnNumbers, ",")
End Function
Function isColumnAllowed(ByVal OrigFileName As String, columnName As String) As Boolean
Select Case OrigFileName
Case "file1"
Forbidden = Split("CASE NOTE", "/")
Case "file2"
Forbidden = Split("Description", "/")
Case "file3"
Forbidden = Split("Item/ Address", "/")
End Select
isColumnAllowed = (UBound(Filter(Forbidden, columnName)) = -1)
End Function
This is what I have now and is working:
If LEN(ColumnToRemove)>0 Then
ColumnToRemoveCol = split(ColumnToRemove, "|") 'set collection of header strings to skip column
For L = 1 To vSheet.UsedRange.Columns.Count
For x = 0 to UBound(ColumnToRemoveCol)
AddCol = 0 'ColumnToRemoveCol can have more than 1 item, that may cause any column to be added more than once; we will use the true/false logic via 0 and 1 to avoid that doubling
If vSheet.cells(1, l)=ColumnToRemoveCol(x) Then
AddCol = AddCol + 1
End If
Next
If AddCol =0 Then ColumnNumbers = ColumnNumbers&","&L
Next
Else
For L = 1 To vSheet.UsedRange.Columns.Count
ColumnNumbers = ColumnNumbers&","&L
Next
End If
If LEFT(ColumnNumbers, 1)="," Then ColumnNumbers=MID(ColumnNumbers, 2)
If RIGHT(ColumnNumbers, 1)="," Then ColumnNumbers=MID(ColumnNumbers, 1, LEN(ColumnNumbers)-1)
Printing the columns for first excel file in my case gives the next line:
ColumnNumbers: 1,2,3,4,5,6,7,8,10,11,12,15,16,17
Further usage:
getColumns = Split(ColumnNumbers, ",")
For rc = 1 To vSheet.UsedRange.Rows.Count
For coc = 0 To UBound(getColumns)
cc = cInt(getColumns(coc))
vtext = vSheet.cells(rc,cc)
.....
Next
Next

VBA Excel Populating cells based on previous existence

I haven't seen this addressed yet, but I think that might be because I don't know how to phrase my problem concisely. Here's an example of what I'd like to try and do:
Given a column which holds state initials check output sheet if that state has been found before. If it hasn't then populate a new cell with that state's initials and initialize the count (number of times state has been found) to one. If the state's initials are found in a cell within the output sheet then increment the count by one.
With this, if we have a 50,000 (or however many) lined excel sheet that has states in random order (states may or may not be repeated) we will be able to create a clean table which outputs which states are in the raw data sheet and how many times they appeared. Another way to think about this is coding a pivot table, but with less information.
There's a couple of ways that I've thought about how to complete this, I personally think none of these are very good ideas but we'll see.
Algorithm 1, all 50 states:
Create 50 string variables for each state, create 50 long variables for the counts
Loop through raw data sheet, if specific state found then increment appropriate count (this would require 50 if-else statements)
Output results
Overall..... terrible idea
Algorithm 2, flip-flop:
Don't create any variables
If a state is found in raw data sheet , look in output sheet to check if state has been found before
If state has been found before, increment cell adjacent by one
If state has not been found before, change next available blank cell to state initials and initialize cell adjacent to one
Go back to raw data sheet
Overall..... this could work, but I feel as if it would take forever, even with raw data sheets that aren't very big but it has the benefit of not wasting memory like the 50 states algorithm and less lines of code
On a side note, is it possible to access a workbook's (or worksheet's) cells without activating that workbook? I ask because it would make the second algorithm run much quicker.
Thank you,
Jesse Smothermon
A couple of point that will speed up your code:
You don't need to active workbooks, worksheets or ranges to access them
eg
DIM wb as workbook
DIM ws as worksheet
DIM rng as range
Set wb = Workbooks.OpenText(Filename:=filePath, Tab:=True) ' or Workbooks("BookName")
Set ws = wb.Sheets("SheetName")
Set rng = ws.UsedRange ' or ws.[A1:B2], or many other ways of specifying a range
You can now refer to the workbook/sheet/range like
rng.copy
for each cl in rng.cells
etc
Looping through cells is very slow. Much faster to copy the data to a variant array first, then loop through the array. Also, when creating a large amount of data on a sheet, better to create it in a variant array first then copy it to the sheet in one go.
DIM v As Variant
v = rng
eg if rng refers to a range 10 rows by 5 columns, v becomes an array of dim 1 to 10, 1 to 5. The 5 minutes you mention would probably be reduced to seconds at most
Sub CountStates()
Dim shtRaw As Excel.Worksheet
Dim r As Long, nr As Long
Dim dict As Object
Dim vals, t, k
Set dict = CreateObject("scripting.dictionary")
Set shtRaw = ThisWorkbook.Sheets("Raw")
vals = Range(shtRaw.Range("C2"), _
shtRaw.Cells(shtRaw.Rows.Count, "C").End(xlUp)).Value
nr = UBound(vals, 1)
For r = 1 To nr
t = Trim(vals(r, 1))
If Len(t) = 0 Then t = "Empty"
dict(t) = dict(t) + 1
Next r
For Each k In dict.keys
Debug.Print k, dict(k)
Next k
End Sub
I implemented my second algorithm to see how it would work. The code is below, I did leave out little details in the actual problem to try and be more clear and get to the core problem, sorry about that. With the code below I've added the other "parts".
Code:
' this number refers to the raw data sheet that has just been activated
totalRow = ActiveSheet.Range("A1").End(xlDown).Row
For iRow = 2 To totalRow
' These are specific to the company needs, refers to addresses
If (ActiveSheet.Cells(iRow, 2) = "BA") Then
badAddress = badAddress + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "C") Then
coverageNoListing = coverageNoListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "L") Then
activeListing = activeListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "NC") Then
noCoverageNoListing = noCoverageNoListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "NL") Then
inactiveListing = inactiveListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "") Then
noHit = noHit + 1
End If
' Algorithm beginning
' If the current cell (in state column) has something in it
If (ActiveSheet.Cells(iRow, 10) <> "") Then
' Save value into a string variable
tempState = ActiveSheet.Cells(iRow, 10)
' If this is also in a billable address make variable true
If (ActiveSheet.Cells(iRow, 2) = "C") Or (ActiveSheet.Cells(iRow, 2) = "L") Or (ActiveSheet.Cells(iRow, 2) = "NL") Then
boolStateBillable = True
End If
' Output sheet
BillableWorkbook.Activate
For tRow = 2 To endOfState
' If the current cell is the state
If (ActiveSheet.Cells(tRow, 9) = tempState) Then
' Get the current hit count of that state
tempStateTotal = ActiveSheet.Cells(tRow, 12)
' Increment the hit count by one
ActiveSheet.Cells(tRow, 12) = tempStateTotal + 1
' If the address was billable then increment billable count
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow, 11)
ActiveSheet.Cells(tRow, 11) = tempStateBillable + 1
End If
Exit For
' If the tempState is unique to the column
ElseIf (tRow = endOfState) Then
' Set state, totalCount
ActiveSheet.Cells(tRow - 1, 9) = tempState
ActiveSheet.Cells(tRow - 1, 12) = 1
' Increment the ending point of the column
endOfState = endOfState + 1
' If it's billable, indicate with number
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow - 1, 11)
ActiveSheet.Cells(tRow - 1, 11) = tempStateBillable + 1
End If
End If
Next
' Activate raw data workbook
TextFileWorkbook.Activate
' reset boolean
boolStateBillable = False
Next
I ran it once and it seems to have worked. The problem is that it took roughly five minutes or so, the original code takes 0.2 (rough guess). I think the only way to make the code perform quicker is to somehow be able to not activate the two workbooks over and over. This means that the answer is not complete but I will edit if I figure out the rest.
Note I will revisit pivot tables to see if I can do everything that I need to in them, as of now it looks like there are a couple of things that I won't be able to change but I'll check
Thank you,
Jesse Smothermon
I kept with the second algorithm. There is the dictionary option that I forgot but I'm still not very comfortable with how it works and I generally don't understand it quite yet. I played with the code for a bit and changed some thing up, it now works faster.
Code:
' In output workbook (separate sheet)
Sheets.Add.Name = "Temp_Text_File"
' Opens up raw data workbook (originally text file
Application.DisplayAlerts = False
Workbooks.OpenText Filename:=filePath, Tab:=True
Application.DisplayAlerts = True
Set TextFileWorkbook = ActiveWorkbook
totalRow = ActiveSheet.Range("A1").End(xlDown).Row
' Copy all contents of raw data workbook
Cells.Select
Selection.Copy
BillableWorkbook.Activate
' Paste raw data into "Temp_Text_File" sheet
Range("A1").Select
ActiveSheet.Paste
ActiveWorkbook.Sheets("Billable_PDF").Select
' Populate long variables
For iRow = 2 To totalRow
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "BA") Then
badAddress = badAddress + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "C") Then
coverageNoListing = coverageNoListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "L") Then
activeListing = activeListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NC") Then
noCoverageNoListing = noCoverageNoListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NL") Then
inactiveListing = inactiveListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "") Then
noHit = noHit + 1
End If
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 10) <> "") Then
tempState = ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 10)
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "C") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "L") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NL") Then
boolStateBillable = True
End If
'BillableWorkbook.Activate
For tRow = 2 To endOfState
If (ActiveSheet.Cells(tRow, 9) = tempState) Then
tempStateTotal = ActiveSheet.Cells(tRow, 12)
ActiveSheet.Cells(tRow, 12) = tempStateTotal + 1
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow, 11)
ActiveSheet.Cells(tRow, 11) = tempStateBillable + 1
End If
Exit For
ElseIf (tRow = endOfState) Then
ActiveSheet.Cells(tRow, 9) = tempState
ActiveSheet.Cells(tRow, 12) = 1
endOfState = endOfState + 1
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow, 11)
ActiveSheet.Cells(tRow, 11) = tempStateBillable + 1
End If
End If
Next
'stateOneTotal = stateOneTotal + 1
'If (ActiveSheet.Cells(iRow, 2) = "C") Or (ActiveSheet.Cells(iRow, 2) = "L") Or (ActiveSheet.Cells(iRow, 2) = "NL") Then
' stateOneBillable = stateOneBillable + 1
'End If
'ElseIf (ActiveSheet.Cells(iRow, 10) = "FL") Then
'stateTwoTotal = stateTwoTotal + 1
'If (ActiveSheet.Cells(iRow, 2) = "C") Or (ActiveSheet.Cells(iRow, 2) = "L") Or (ActiveSheet.Cells(iRow, 2) = "NL") Then
' stateTwoBillable = stateTwoBillable + 1
'End If
End If
'TextFileWorkbook.Activate
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "C") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "L") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NL") Then
billableCount = billableCount + 1
End If
boolStateBillable = False
Next
' Close raw data workbook and raw data worksheet
Application.DisplayAlerts = False
TextFileWorkbook.Close
ActiveWorkbook.Sheets("Temp_Text_File").Delete
Application.DisplayAlerts = True
Thank you for the comments and suggestions. It is very much appreciated as always.
Jesse Smothermon

Resources