Moving multiple images to another worksheet using VBA - new location - excel

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

Related

copy and morph several worksheets into one worksheet for pivot

I am trying to combine several worksheets into one worksheet via VBA to resolve a matrix type into a pivot friendly form. This works nicely so far, except for the fact that after each loop one additional line gets appendended.
Here is what I get:
Result
And this is what i would like to have:
Desired outcome
Public Sub CopyData()
Dim iRowCount, iTableCount, iRowCountTarget, iColumnCount, iRowCountUser, iWorksheetsCounter, iNumberOfWorksheets As Integer
Application.ScreenUpdating = False
iColumnCount = 2
iRowCountUser = 1
iWorksheetsCounter = 1
iNumberOfWorksheets = ThisWorkbook.Worksheets.Count - 1
iTableCount = WorksheetFunction.CountA(Range("A:A"))
iTableCountTarget = WorksheetFunction.CountA(ActiveWorkbook.Worksheets(iNumberOfWorksheets + 1).Range("A:A"))
For iWorksheetsCounter = 1 To iNumberOfWorksheets
For iRowCount = 1 To iTableCount
With ActiveWorkbook
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 3) = ActiveWorkbook.Worksheets(iWorksheetsCounter).Cells(iRowCountUser, iColumnCount)
.Worksheets(iWorksheetsCounter).Cells(iRowCount + 1, 1).Copy
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 1).PasteSpecial
.Worksheets(iWorksheetsCounter).Cells(iRowCount + 1, 2).Copy
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 2).PasteSpecial
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 4) = iTableCountTarget
End With
iTableCountTarget = iTableCountTarget + 1
Next iRowCount
Next iWorksheetsCounter
Application.ScreenUpdating = True
End Sub
where am I adding the additional line? I cannot seem to get around it.
thanks for all the pointers!
EDIT: Added a picture of the source table upon request.
All tables should be the same size, but I might want to extend that to more columns in individual tables later down the line
Source Table(s)
Another way to do it :
Dim oWs, oFinalWs As Worksheet
Dim finalLastRow As Integer
Set oFinalWs = ThisWorkbook.Worksheets("final")
oFinalWs.Cells.ClearContents
For Each oWs In ThisWorkbook.Worksheets
If Not oWs.Name = oFinalWs.Name Then
finalLastRow = oFinalWs.Cells(oFinalWs.Cells.Rows.Count, 1).End(xlUp).Row
oWs.Cells(1, 1).CurrentRegion.Copy oFinalWs.Cells(finalLastRow, 1)
End If
Next

VBA (RFC) SAP export to excel

I am writing a VB application for connecting to a sap system (using rfc).
Everything works fine and I do get a connection and the data as well.
Nevertheless the code for saving the accessed data and writing it to a excel file is really slow.
After the connection I call RFC_READ_TABLE, which returns with a result in <5 secs, which is perfect. Writing to excel (cell by cell) is pretty slow.
Is there any way to 'export' the whole tblData to excel and not being dependent on writing cell by cell?
Thanks in advance!
If RFC_READ_TABLE.Call = True Then
MsgBox tblData.RowCount
If tblData.RowCount > 0 Then
' Write table header
For j = 1 To Size
Cells(1, j).Value = ColumnNames(j)
Next j
Size = UBound(ColumnNames, 1) - LBound(ColumnNames, 1) + 1
For i = 1 To tblData.RowCount
DoEvents
Textzeile = tblData(i, "WA")
For j = 1 To Size
Cells(i + 1, j).Value = LTrim(RTrim(getPieceOfTextzeile(Textzeile)))
Next j
Next
Else
MsgBox "No entries found in system " & SYSID, vbInformation
End If
Else
MsgBox "ERROR CALLING SAP REMOTE FUNCTION CALL"
End If
Arrays: Faster Than Ranges
If the data was ready (need not to be processed) something like this could be a solution:
Sub Sap()
Const cStrStart As String = "A1" 'First cell of the resulting data
Dim tbldata
Dim arrSap As Variant 'Will become a one-based two dimensional array
Dim oRng As Range
arrSap = tbldata 'Data is in the array.
'Calculate the range: Must be the same size as arrSap
Set oRng = Range(Cells(Range(cStrStart).Row, UBound(arrSap)), _
Cells(Range(cStrStart)).Column, UBound(arrSap, 2))
oRng = arrSap 'Paste array into range.
End Sub
Since you need to process your data from tbldata do what you do not to the range, but to an array which should be much faster:
Sub Sap()
Const cStrStart As String = "A1" 'First cell of the resulting data
Dim arrSap() As Variant
Dim oRng As Range
Dim Size As Integer
If RFC_READ_TABLE.Call = True Then
'-------------------------------------------------------------------------------
MsgBox tbldata.RowCount
If tbldata.RowCount > 0 Then
Size = UBound(ColumnNames, 1) - LBound(ColumnNames, 1) + 1
ReDim arrSap(1 To tbldata.RowCount + 1, 1 To Size) '+ 1 for header
' Write table header
For j = 1 To Size
arrSap(1, j).Value = ColumnNames(j)
Next j
' Write data
For i = 1 + 1 To tbldata.RowCount + 1 '+ 1 for header
DoEvents
'- 1 due to header, don't know what "WA" is
Textzeile = tbldata(i - 1, "WA")
For j = 1 To Size
arrSap(i, j) = _
LTrim(RTrim(getPieceOfTextzeile(Textzeile)))
Next j
Next
'-------------------------------------------------------------------------------
'Calculate the range: Must be the same size as arrSap
Set oRng = Range(Cells(Range(cStrStart).Row, Range(cStrStart).Column), _
Cells(UBound(arrSap) + Range(cStrStart).Row -1, _
UBound(arrSap, 2) + Range(cStrStart).Column -1))
oRng = arrSap
'-------------------------------------------------------------------------------
Else
MsgBox "No entries found in system " & SYSID, vbInformation
End If
Else
MsgBox "ERROR CALLING SAP REMOTE FUNCTION CALL"
End If
End Sub
Now adjust the cStrStart, check the rest of the code and you're good to go.
I haven't created a working example so I edited this code a few times. Check it carefully not to lose data.

Grouping cells during a loop not responding as expected

Background:
I have a sheet named RM that I am pulling milestone data from to a sheet named Finance via a loop (loop is per sheets("RM")). Once the data is pulled forward, the sheet is supposed to group items in two subtotals:
1) Group the milestone activities
2) Group the everything that was pulled over during the loop
Here is the code:
Dim i As Integer
Dim LR As Long, FR As Long
FR = Sheets("Finance").Cells(Sheets("Finance").Rows.Count, 1).End(xlUp).Row
Sheets("Finance").Cells(FR + 1, 1).Value = "Raw Materials"
Sheets("Finance").Cells(FR + 1, 7).Value = Sheets("RM").Cells(12, 2).Value
For i = 16 To 358 Step 18
LR = Sheets("Finance").Cells(Sheets("Finance").Rows.Count, 1).End(xlUp).Row
If Sheets("RM").Cells(i, 4) > 0 And Sheets("RM").Cells(i, 2) = "Fixed" Then
'Milestone row
Sheets("Finance").Cells(LR + 1, 1).Value = Sheets("RM").Cells(i, 1).Value
Sheets("Finance").Cells(LR + 1, 7).Value = Sheets("RM").Cells(i, 4).Value
Sheets("Finance").Rows(LR + 1).Font.Bold = True
'Number
Sheets("Finance").Range(Sheets("Finance").Cells(LR + 2, 1), Sheets("Finance").Cells(LR + 9, 1)).Value = Sheets("RM").Cells(i, 1).Value
'Removed middle section, which pulls over data from different columns
'Group Milestone subactivities
If Sheets("Finance").Cells(LR, 1).Value = Sheets("Finance").Cells(LR - 2, 1).Value Then
Sheets("Finance").Range(Sheets("Finance").Cells(LR + 2, 1), Sheets("Finance").Cells(LR + 9, 1)).EntireRow.Group
Else
End If
Else
End If
Next i
Sheets("Finance").Rows(FR + 1).Font.Bold = True
If LR - FR > 1 Then
Sheets("Finance").Range(Sheets("Finance").Rows(FR + 2), Sheets("Finance").Rows(LR)).EntireRow.Group
Else
End If
Issue:
The grouping for the milestone events is not coming over appropriately. When the code runs, only some of the milestones get their grouping, though the overarching grouping occurs.
In a list of 10 milestones, 1 and 10 do not have milestone grouping, but 2-9 do group.
I thought I had an issue with the if-statement itself, that If LR-FR>2 then, but in stepping-through, I found something weird.
As I step-through with F8, I realized that the data that I .copy/.pastespecial does not show up until after one or two loops have occurred. The grouping then shows up for the last visually-added data that was pasted. Then subsequent data shows up until the last bit.
Question:
Is there a way to force the paste to display data? Is there anything else that would cause this activity from Excel/VBA?
Any help in resolution would be appreciated.
Two things happened to work-around the issue:
1) I had to add another line so the Milestone groupings did not end on the same line as the Section grouping (in this case, after the loop in the subroutine posted in the question).
Dim LR as Long
LR = Sheets("Finance").Cells(Sheets("Finance").Rows.Count, 7).End(xlUp).Row
Sheets("Finance").Cells(LR + 1, 7).Value = "-"
Sheets("Finance").Rows(LR + 1).Font.Bold = True
2) I pulled all of the grouping out to the end, after the loops.
The code for grouping ends up looking like:
Dim a as Integer
LR = Sheets("Finance").Cells(Sheets("Finance").Rows.Count, 7).End(xlUp).Row
For i = 5 To LR
If Sheets("Finance").Cells(i, 1).Font.Bold = False Then
Sheets("Finance").Rows(i).EntireRow.Group
Else
End If
Next i
'Group between sheets
a = Sheets("Finance").Columns(1).Find(What:="Not Raw Materials", LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Row
Sheets("Finance").Range(Sheets("Finance").Rows(4), Sheets("Finance").Rows(a - 1)).EntireRow.Group
In the end, I had to make sure the grouping was from the smallest increments to the largest increments to ensure that I did not lose functionality of the mass-grouping (subtotal) toggles. I would often lose the last milestone's subtotal toggle.

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

Microsoft Excel 2010 Web Query Macro: Pulling Multiple Pages From One

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

Resources