I am looking to find some help on this Macro.. The idea is, upon execution the Macro will pull The Data from a Web Page (I.E http://www.link.com/id=7759) and place it into let's say Sheet2, and then Open up Page 2, and place it right below Page 1's Data in Sheet 2.... And So on and So on until a set Page Number.. Ideally I would like it just to pull The following in order;
Title
Artist
Type
Paper Size
Image Size
Retail Prize
Quantity
And further more it is ideal that is placed in proper columns and rows of 4 and 8 Rows down(Columns Across just like in the web page).
Any help on this would be greatly, greatly appreciated. I have done some research and found similar macros, sadly have had no luck getting them to work for me. Mainly VB's fail to go through as well.
Bit of useful info (maybe) I figured this out when I was trying to write my own, maybe it will save who ever helps some time..
.WebTables = "8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38"
Those are the tables for each item I want to put into the Que...
Here's a sample method to get you going
Based on a few assumptions
Workbook contains a Sheet to hold query data called "Query"
Workbook contains a Sheet to put the data in called "AllData"
All old data is removed on running the macro
I think you need to include Table 7 in the qyuery
Pages to process is hard coded as For Pg = 1 To 1 , change this to suit
.
Sub QueryWebSite()
Dim shQuery As Worksheet, shAllData As Worksheet
Dim clData As Range
Dim qts As QueryTables
Dim qt As QueryTable
Dim Pg As Long, i As Long, n As Long, m As Long
Dim vSrc As Variant, vDest() As Variant
' setup query
Set shQuery = ActiveWorkbook.Sheets("Query")
Set shAllData = ActiveWorkbook.Sheets("AllData")
'Set qt = shQuery.QueryTables(1)
On Error Resume Next
Set qt = shQuery.QueryTables("Liebermans")
If Err.Number <> 0 Then
Err.Clear
Set qt = shQuery.QueryTables.Add( _
Connection:="URL;http://www.liebermans.net/productlist.aspx?id=7759&page=1", _
Destination:=shQuery.Cells(1, 1))
With qt
.Name = "Liebermans"
.WebSelectionType = xlSpecifiedTables
.WebFormatting = xlWebFormattingNone
.WebTables = "7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38"
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
End If
On Error GoTo 0
i = InStr(qt.Connection, "&page=")
' clear old data
shAllData.UsedRange.ClearContents
shAllData.Cells(1, 1) = "Title"
shAllData.Cells(1, 2) = "Artist"
shAllData.Cells(1, 3) = "Type"
shAllData.Cells(1, 4) = "Paper Size"
shAllData.Cells(1, 5) = "Image Size"
shAllData.Cells(1, 6) = "Price"
shAllData.Cells(1, 7) = "Quantity"
m = 0
ReDim vDest(1 To 10000, 1 To 7)
For Pg = 1 To 1
' Query Wb site
qt.Connection = Left(qt.Connection, i + 5) & Pg
qt.Refresh False
' Process data
vSrc = qt.ResultRange
n = 2
Do While n < UBound(vSrc, 1)
If vSrc(n, 1) <> "" And vSrc(n - 1, 1) = "" Then
m = m + 1
vDest(m, 1) = vSrc(n, 1)
End If
If vSrc(n, 1) Like "Artist:*" Then vDest(m, 2) = Trim(Mid(vSrc(n, 1), 8))
If vSrc(n, 1) Like "Type:*" Then vDest(m, 3) = Trim(Mid(vSrc(n, 1), 6))
If vSrc(n, 1) Like "Paper Size:*" Then vDest(m, 4) = Trim(Mid(vSrc(n, 1), 12))
If vSrc(n, 1) Like "Image Size:*" Then vDest(m, 5) = Trim(Mid(vSrc(n, 1), 12))
If vSrc(n, 1) Like "Retail Price:*" Then vDest(m, 6) = Trim(Mid(vSrc(n, 1), 14))
If vSrc(n, 1) Like "Quantity in stock:*" Then vDest(m, 7) = Trim(Mid(vSrc(n, 1), 19))
n = n + 1
Loop
Next
' Put data in sheet
shAllData.Cells(2, 1).Resize(m, 7) = vDest
End Sub
Related
enter image description here
Many thanks for your reply, Please find attached a picture of the user form I Got the data in the list box by some other ways no I am facing an issue to update and edit the data. I am trying to call the data from Listbox to textbox and checkboxes by below code for Editing.
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean) 'UPDATE LISBOX DATA
Dim p As Integer
Me.ComboBoxitem.Value = Me.ListBox1.List(Me.ListBox1.ListIndex, 1)
For p = 0 To Me.ListBox1.ListCount < 1
Me.CheckBoxSmall.Value = Me.ListBox1.List(p, 3)
Me.CheckBoxMedium.Value = Me.ListBox1.List(p, 3)
Me.CheckBoxLarge.Value = Me.ListBox1.List(p, 3)
Me.CheckBoXL.Value = Me.ListBox1.List(p, 3)
Me.CheckBoXXL.Value = Me.ListBox1.List(p, 3)
Me.CheckBoXXXL.Value = Me.ListBox1.List(p, 3)
Me.txtsmallqty.Value = Me.ListBox1.List(p, 4)
Me.TextBoxmedium.Value = Me.ListBox1.List(p, 4)
Me.TextBoxlarge.Value = Me.ListBox1.List(p, 4)
Me.TextBoXL.Value = Me.ListBox1.List(p, 4)
Me.TextBoxxL.Value = Me.ListBox1.List(p, 4)
Me.TextBoxxxL.Value = Me.ListBox1.List(p, 4)
Next
Me.TextBox1.Value = Me.ListBox1.List(Me.ListBox1.ListIndex, 0)
End Sub
and for update the data in excel sheet after editing , I am using below code :
Private Sub CommandButton1_Click() ' Update Data
Dim L As Long
Dim th As Worksheet
Set th = ThisWorkbook.Sheets("Data")
L = Application.WorksheetFunction.Match(CLng(Me.TextBox1.Value), th.Range("A1:A1000"), 0)
th.Range("B" & L) = Me.ComboBoxitem.Value
th.Range("D" & L) = Me.CheckBoxSmall.Value
th.Range("D" & L) = Me.CheckBoxMedium.Value
th.Range("D" & L).Value = Me.CheckBoxLarge.Value
th.Range("D" & L).Value = Me.CheckBoXL.Value
th.Range("D" & L).Value = Me.CheckBoXXL.Value
th.Range("D" & L).Value = Me.CheckBoXXXL.Value
th.Range("E" & L) = Me.txtsmallqty.Value
th.Range("E" & L) = Me.TextBoxmedium.Value
th.Range("E" & L) = Me.TextBoxlarge.Value
th.Range("E" & L) = Me.TextBoXL.Value
th.Range("E" & L) = Me.TextBoxxL.Value
th.Range("E" & L) = Me.TextBoxxxL.Value
Me.CheckBoxSmall.Value = False
Me.CheckBoxMedium.Value = False
Me.CheckBoxLarge.Value = False
Me.CheckBoXL.Value = False
Me.CheckBoXXL.Value = False
Me.CheckBoXXXL.Value = False
Me.txtsmallqty.Value = ""
Me.TextBoxmedium.Value = ""
Me.TextBoxlarge.Value = ""
Me.TextBoXL.Value = ""
Me.TextBoxxL.Value = ""
Me.TextBoxxxL.Value = ""
Me.TextBox1.Value = ""
End Sub
Addition due to comment:
"I am trying to pull Listbox data in 6 checkboxes and 6 text boxes from the first code mention above, the Issue I am facing from this code, shows only data from the first line of Listbox to all text boxes and checkboxes.
By the mean of the second code I have to update data in excel sheet."
But I am not able to get the perfect result, you are requested to please review the above Code and let me know where I am Mistaking.
Your Kind Response will be Highly Appreciated.
As you are displaying always six rows per chosen item (corresponding to six sizes of Small,Medium,...,XXXL) with item info only in the 1st row, a main issue is to get the correct .ListIndex by doubleclicking to any row within the listbox.
1. The start row index p (containing the serial# and product name) can be calculated from the currently double clicked .ListIndex using an int(eger) division multiplied by six rows to get to the first row (see section 1):
p = (Me.ListBox1.ListIndex \ 6) * 6
Example: a double click into .ListIndex of 0..5 results in the start row index p = 0, of 6..11 in 6, ... - i.e. always returning the first row of a bundle of six rows containing sizes.
2. To avoid endless assignments I defined two variant arrays (chkboxes and txtboxes) containing the checkbox and textbox names (see section 2). - Another frequently used method consists in enumerating the control names facilitating assignments in a later loop.
3. The 3rd step assigns the listbox'es main info (3a) and the size-related values (3b) to all single controls; the latter action is executed in a loop referring to the controls via Me.Controls(chkboxes(i)).Value and Me.Controls(txtboxes(i)).Value.
The following code example should give you a start and allow to finish the 2nd procedure by yourself (remind: don't overload a post by too many independant questions, focus to one issue :-;)
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean) 'UPDATE LISBOX DATA
'1. get the start row containing the serial code,
' (even if doubleclicked in one of the five following rows)
Dim p As Long ' instead of Integer
p = (Me.ListBox1.ListIndex \ 6) * 6 ' each item has 6 rows (sizes available)
'2. define arrays containing checkbox|textbox names
Dim chkboxes, txtboxes
chkboxes = Split("CheckBoxSmall,CheckBoxMedium,CheckBoxLarge,CheckBoXL,CheckBoXXL,CheckBoXXXL", ",")
txtboxes = Split("txtsmallqty,TextBoxmedium,TextBoxlarge,TextBoXL,TextBoXXL,TextBoxxxL", ",")
'3. a) write item name & Serial# to corresponding userform controls
Me.ComboBoxitem.Value = Me.ListBox1.List(p, 1) ' Item name
Me.TextBox1.Value = Me.ListBox1.List(p, 0) ' Serial number
'3. b) loop through all six rows representing sizes
Dim i As Long
For i = 0 To 5 ' listbox items and both ctrl arrays are 0-based!
Me.Controls(chkboxes(i)).Value = CBool(Me.ListBox1.List(p + i, 3)) ' 4th column has index 3!
Me.Controls(txtboxes(i)).Value = Me.ListBox1.List(p + i, 4) ' 5th column has index 3!
Next i
End Sub
I have a userform with 7 combo boxes that are used to search data from the worksheet. I intend to present column 6(mass) and 8(index) as ranges i.e. for mass: 0.007-0.1; 0.11-2.5; 0.251-0.5 etc. The other 5 combo boxes are just absolute values (not range).I'm attempting to loop through the cells in the data sheet(shD) and whenever the row matches matches all selections made on the userform; then the entire row is copied to the results sheet(shR). The user may leave some of the combo boxes blank, but they should still be able to get results. What the code is doing now is may be say in the time combobox(cbInj) I selected say 15 seconds; the code will include 20 seconds which does not match the 15sec on the combo box. Here is my code;
'combo boxes variable definition, in order to compact and make the code easy to be understood:
Set cbPr = User_search.Cbx_Project_code
Set cbTr = User_search.Cbx_TrueNOC
Set cbDn = User_search.Cbx_DNAmass
Set cbK = User_search.Cbx_Kit
Set cbQ = User_search.Cbx_QIndex
Set cbInj = User_search.Cbx_Injection_time
Set cbInstr = User_search.Cbx_Instrument
'Check selection for mass and present it as a range
If Len(cbDn.Value) > 0 Then
arrDn = Split(cbDn.Value, "-")
mnDn = CDbl(arrDn(0))
mxDn = CDbl(arrDn(1))
End If
'checkfor Index if selected and present it as a range
If Len(cbQ.Value) > 0 Then
arrQ = Split(cbQ.Value, "-")
mnQ = CVar(arrQ(0))
mxQ = CVar(arrQ(1))
End If
'count the total rows on Data
totD = shD.Range("B" & Rows.Count).End(xlUp).Row 'last row of "Data" sheet
For i = 5 To totD
vDn = shD.Cells(i, 6).Value
vQ = shD.Cells(i, 8).Value
If (Trim(shD.Cells(i, 2)) = Trim(cbPr.Value) Or cbPr.Value = "") And _
(Trim(shD.Cells(i, 5)) = Trim(cbTr.Value) Or cbTr.Value = "") And _
vDn > mnDn And vDn <= mxDn Or cbDn.Value = "" And _
(Trim(shD.Cells(i, 7)) = Trim(cbK.Value) Or cbK.Value = "") And _
vQ > mnQ And vQ <= mxQ Or cbQ.Value = "" And _
(Trim(shD.Cells(i, 9)) = Trim(cbInj.Value) Or cbInj.Value = "") And _
(Trim(shD.Cells(i, 10)) = Trim(cbInstr.Value) Or cbInstr.Value = "") Then
totR = shR.Cells(Rows.Count, 1).End(xlUp).Row
shD.Rows(i).EntireRow.Copy Destination:=shR.Cells(totR + 1, 1)
End If
Next i
Slight logic problem in your "range" tests - eg:
vQ > mnQ And vQ <= mxQ Or cbQ.Value = "" And _
should be
((vQ > mnQ And vQ <= mxQ) Or cbQ.Value = "") And _
I would do something like this. Individual tests are faster, since there's no need to continue checking after any failed test
Sub Tester()
Dim cbPr, cbTr, cbDn, cbk, cbQ, cbInj, cbInstr 'all variants
Dim rw As Range, isMatch As Boolean, arrCrit
'get combo boxes values
cbPr = Trim(User_search.Cbx_Project_code.Value)
cbTr = Trim(User_search.Cbx_TrueNOC.Value)
cbDn = Trim(User_search.Cbx_DNAmass.Value)
If Len(cbDn) > 0 Then cbDn = Split(cbDn, "-") 'convert to array
cbk = Trim(User_search.Cbx_Kit.Value)
cbQ = Trim(User_search.Cbx_QIndex.Value)
If Len(cbQ) > 0 Then cbDn = Split(cbQ, "-") 'convert to array
cbInj = Trim(User_search.Cbx_Injection_time.Value)
cbInstr = Trim(User_search.Cbx_Instrument.Value)
arrCrit = Array(2, cbPr, 5, cbTr, 6, cbDn, 7, cbk, 8, cbQ, 9, cbInj, 10, cbInstr)
For i = 5 To shD.Range("B" & Rows.Count).End(xlUp).Row
Set rw = shD.Rows(i)
For n = LBound(arrCrit) To UBound(arrCrit) - 1 Step 2
isMatch = CellIsMatch(rw.Cells(arrCrit(n)), arrCrit(n + 1))
If Not isMatch Then Exit For
Next n
If isMatch Then rw.Copy shR.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Next i
End Sub
'Does a cell value match the supplied criteria?
' Criteria could be a range of two numeric values
Function CellIsMatch(cell As Range, crit) As Boolean
Dim v
v = cell.Value
If Len(v) > 0 Then
'is the criteria an array (range) ?
If TypeName(crit) Like "*()" Then
'assumes v is numeric
CellIsMatch = (v > CDbl(Trim(crit(0))) And _
v < CDbl(Trim(crit(1))))
Else
CellIsMatch = (Trim(v) = crit) Or Len(crit) = 0
End If
End If
End Function
I am creating a new sheet with the goal of reorganizing the information on another sheet. I have been able to move all other information to the other sheet in the format needed, but I can not move images/pictures of the parts.
I have tried using the code shown below, but referencing the cell the images are in, but it does not copy. I did a little research and looked at if there was a simple way to move images just by copy-pasting cells through VBA and it does not seem to work. I also look at trying to rename all the shapes, but to no success.
'find the last row of values
Worksheets("Eyelets").Activate
LastRow = Cells.Find("*", SearchOrder:=xlByRows,
SearchDirection:=xlPrevious).Row + 3
Worksheets("Plot").Activate
'1st column of values
For i = 2 To LastRow Step 4
Count = Count + 1
x = i + Count
'Store all variables in the row
RDPNHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 0)
FDPNHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 1)
WRHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 4)
MatHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 9)
DiamHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 5).Value
'Move All Part Numbers to next sheet.
Worksheets("Plot").Range("A1").Offset(x - 2, 0) = RDPNText & RDPNHold
Worksheets("Plot").Range("A1").Offset(x - 1, 0) = FDPNText & FDPNHold
Worksheets("Plot").Range("A1").Offset(x, 0) = WRText & WRHold
Worksheets("Plot").Range("A1").Offset(x + 1, 0) = MatText & MatHold & DiamText & DiamHold
'Bold Specific parts of the cells
Worksheets("Plot").Range("A1").Offset(x - 2, 0).Characters(Len(lngIDStart), 3).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x - 1, 0).Characters(Len(lngIDStart), 3).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x, 0).Characters(Len(lngIDStart), 3).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x + 1, 0).Characters(Len(lngIDStart), 4).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x + 1, 0).Characters(Len(lngIDStart) + 13, 5).Font.Bold = True
Next i
Information not formateed This image shows how the information is already organized (I changed values due to work-related information)
Formatted Information This image shows how I am trying to format the information, and as shown the blank space for the images.
Any ideas or suggestions are greatly appreciated!
Here's a starting point:
Sub Tester()
Dim shtSource As Worksheet, shtDest As Worksheet
'....
Set shtSource = Worksheets("Eyelets")
Set shtDest = Worksheets("Plots")
'....
If CopyPicFromCell(shtSource.Range("A1").Offset(i - 1, 2)) Then
'copied the picture, so paste to shtDest
shtDest.Paste
With shtDest.Shapes(shtDest.Shapes.Count)
.Top = shtDest.Range("A1").Offset(0, 1).Top
.Left = shtDest.Range("A1").Offset(0, 1).Left
End With
End If
End Sub
'see if there's a shape to be copied from a given cell
' return True if one was found
Function CopyPicFromCell(c As Range)
Const MARGIN As Long = 10 '<< how far the picture can be out of place
Dim shp As Shape
For Each shp In c.Parent.Shapes
'check the TopLeftCell and the shape's position
If shp.TopLeftCell.Address = c.Address Or _
(Abs(shp.Left - c.Left) < MARGIN And Abs(shp.Top - c.Top) < MARGIN) Then
shp.Copy
CopyPicFromCell = True
Exit For '<< done checking
End If
Next shp
End Function
I have an MS Access VBA code that generates an Excel spreadsheet shown below, and I need to make my page break output from this:
into this:
programmatically in MS Access VBA.
I have tried already a bunch of codes (see snippets below) but somehow none of them did the trick nor even the slightest change.
Code Snippet #1)
ActiveWindow.View = xlPageBreakPreview
ActiveSheet.ResetAllPageBreaks
i = 1
If ActiveSheet.HPageBreaks.Count > 0 Then
Do
Set ActiveSheet.HPageBreaks(i).Location = Range("A" & (i * 70) + 1)
If i = ActiveSheet.HPageBreaks.Count Then Exit Do
i = i + 1
Loop
End If
Do Until Cells((i * 70) + 3, 1).Value = ""
ActiveSheet.HPageBreaks.Add Before:=Range("a" & (i * 73) + 1)
i = i + 1
Loop
ActiveWindow.View = xlNormalView
Code Snippet #2)
Dim Rng As Excel.Range
Set Rng = xls.Rows("1:75")
Rng(75).PageBreak = -4135
Code Snippet #3)
xls.HPageBreaks.Add Before:=xls.Cells(73, 1)
Any assistance on this is highly appreciated. Thanks a bunch! :)
I'm not understanding your snippets very well, but based on the screenshot, you want to print it on one page containing everything. Something like this sets the print area to 1 page x 1 page in excel -
Sub breaks()
Dim rLastCol As Long
Dim rLastRow As Long
With ActiveSheet
rLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
rLastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
With .PageSetup
.PrintArea = Range("A1", Cells(rLastRow, rLastCol)).Address
.FitToPagesWide = 1
.FitToPagesTall = False
End With
End With
End Sub
Of course, this uses the last used cell in column A and in Row 1, so the most bottom-right non-blank.
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