I've divided an excel worksheet into different sections, each section being 20 rows in size (example: Section 1 = rows 132 to 152, Section 2 = rows 153 to 173, etc.). There are 100 sections. I'm running a procedure in VBA that, for each section, will hide a certain number of rows based on a desired number of rows for each section. After about running the routine on 23 sections, I get a "Procedure too Large" error. I was told that I should run a sub procedure to solve the problem. I'm not sure how to do that. I'm using Sub proc1(), but it's not working. Here is the first part of the code, followed by the Sub proc1(). It's not working. I'm now getting the following error immediately after the Sup proc1() line:
Ambiguous name detected: Worksheet_Change
If anyone can help me with the proper code after the Sub proc1() that would help immensely!
Private Sub Worksheet_Change(ByVal Target As Range)
ActiveSheet.Unprotect
ActiveSheet.Activate
If Not Application.Intersect(Range("G20"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "0": Rows("132:152").EntireRow.Hidden = True
Case Is = "1": Rows("134:152").EntireRow.Hidden = True
Rows("123:133").EntireRow.Hidden = False
Case Is = "2": Rows("135:152").EntireRow.Hidden = True
Rows("123:134").EntireRow.Hidden = False
Case Is = "3": Rows("136:152").EntireRow.Hidden = True
Rows("123:135").EntireRow.Hidden = False
Case Is = "4": Rows("137:152").EntireRow.Hidden = True
Rows("123:136").EntireRow.Hidden = False
Case Is = "5": Rows("138:152").EntireRow.Hidden = True
Rows("123:137").EntireRow.Hidden = False
Case Is = "6": Rows("139:152").EntireRow.Hidden = True
Rows("123:138").EntireRow.Hidden = False
Case Is = "7": Rows("140:152").EntireRow.Hidden = True
Rows("123:139").EntireRow.Hidden = False
Case Is = "8": Rows("141:152").EntireRow.Hidden = True
Rows("123:140").EntireRow.Hidden = False
Case Is = "9": Rows("142:152").EntireRow.Hidden = True
Rows("123:141").EntireRow.Hidden = False
Case Is = "10": Rows("143:152").EntireRow.Hidden = True
Rows("123:142").EntireRow.Hidden = False
Case Is = "11": Rows("144:152").EntireRow.Hidden = True
Rows("123:143").EntireRow.Hidden = False
Case Is = "12": Rows("145:152").EntireRow.Hidden = True
Rows("123:144").EntireRow.Hidden = False
Case Is = "13": Rows("146:152").EntireRow.Hidden = True
Rows("123:145").EntireRow.Hidden = False
Case Is = "14": Rows("147:152").EntireRow.Hidden = True
Rows("123:146").EntireRow.Hidden = False
Case Is = "15": Rows("148:152").EntireRow.Hidden = True
Rows("123:147").EntireRow.Hidden = False
Case Is = "16": Rows("149:152").EntireRow.Hidden = True
Rows("123:148").EntireRow.Hidden = False
Case Is = "17": Rows("150:152").EntireRow.Hidden = True
Rows("123:149").EntireRow.Hidden = False
Case Is = "18": Rows("151:152").EntireRow.Hidden = True
Rows("123:150").EntireRow.Hidden = False
Case Is = "19": Rows("152:152").EntireRow.Hidden = True
Rows("123:151").EntireRow.Hidden = False
Case Is = "20": Rows("123:152").EntireRow.Hidden = False
End Select
End If
and so on...then:
If Not Application.Intersect(Range("G43"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "0": Rows("615:635").EntireRow.Hidden = True
Case Is = "1": Rows("617:635").EntireRow.Hidden = True
Rows("615:616").EntireRow.Hidden = False
Case Is = "2": Rows("618:635").EntireRow.Hidden = True
Rows("615:617").EntireRow.Hidden = False
Case Is = "3": Rows("619:635").EntireRow.Hidden = True
Rows("615:618").EntireRow.Hidden = False
Case Is = "4": Rows("620:635").EntireRow.Hidden = True
Rows("615:619").EntireRow.Hidden = False
Case Is = "5": Rows("621:635").EntireRow.Hidden = True
Rows("615:620").EntireRow.Hidden = False
Case Is = "6": Rows("622:635").EntireRow.Hidden = True
Rows("615:621").EntireRow.Hidden = False
Case Is = "7": Rows("623:635").EntireRow.Hidden = True
Rows("615:622").EntireRow.Hidden = False
Case Is = "8": Rows("624:635").EntireRow.Hidden = True
Rows("615:623").EntireRow.Hidden = False
Case Is = "9": Rows("625:635").EntireRow.Hidden = True
Rows("615:624").EntireRow.Hidden = False
Case Is = "10": Rows("626:635").EntireRow.Hidden = True
Rows("615:625").EntireRow.Hidden = False
Case Is = "11": Rows("627:635").EntireRow.Hidden = True
Rows("615:626").EntireRow.Hidden = False
Case Is = "12": Rows("628:635").EntireRow.Hidden = True
Rows("615:627").EntireRow.Hidden = False
Case Is = "13": Rows("629:635").EntireRow.Hidden = True
Rows("615:628").EntireRow.Hidden = False
Case Is = "14": Rows("630:635").EntireRow.Hidden = True
Rows("615:629").EntireRow.Hidden = False
Case Is = "15": Rows("631:635").EntireRow.Hidden = True
Rows("615:630").EntireRow.Hidden = False
Case Is = "16": Rows("632:635").EntireRow.Hidden = True
Rows("615:631").EntireRow.Hidden = False
Case Is = "17": Rows("633:635").EntireRow.Hidden = True
Rows("615:632").EntireRow.Hidden = False
Case Is = "18": Rows("634:635").EntireRow.Hidden = True
Rows("615:633").EntireRow.Hidden = False
Case Is = "19": Rows("635:635").EntireRow.Hidden = True
Rows("615:634").EntireRow.Hidden = False
Case Is = "20": Rows("615:635").EntireRow.Hidden = False
End Select
End If
Call proc1
Call proc2
End Sub
Sub proc1()
If Not Application.Intersect(Range("G44"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "0": Rows("636:656").EntireRow.Hidden = True
Case Is = "1": Rows("638:656").EntireRow.Hidden = True
Rows("636:637").EntireRow.Hidden = False
Case Is = "2": Rows("639:656").EntireRow.Hidden = True
Rows("636:638").EntireRow.Hidden = False
Case Is = "3": Rows("640:656").EntireRow.Hidden = True
Rows("636:639").EntireRow.Hidden = False
Case Is = "4": Rows("641:656").EntireRow.Hidden = True
Rows("636:640").EntireRow.Hidden = False
Case Is = "5": Rows("642:656").EntireRow.Hidden = True
Rows("636:641").EntireRow.Hidden = False
Case Is = "6": Rows("643:656").EntireRow.Hidden = True
Rows("636:642").EntireRow.Hidden = False
Case Is = "7": Rows("644:656").EntireRow.Hidden = True
Rows("636:643").EntireRow.Hidden = False
Case Is = "8": Rows("645:656").EntireRow.Hidden = True
Rows("636:644").EntireRow.Hidden = False
Case Is = "9": Rows("646:656").EntireRow.Hidden = True
Rows("636:645").EntireRow.Hidden = False
Case Is = "10": Rows("647:656").EntireRow.Hidden = True
Rows("636:646").EntireRow.Hidden = False
Case Is = "11": Rows("648:656").EntireRow.Hidden = True
Rows("636:647").EntireRow.Hidden = False
Case Is = "12": Rows("649:656").EntireRow.Hidden = True
Rows("636:648").EntireRow.Hidden = False
....and so on
You can use a loop and a some math to reduce your code a lot:
Private Sub Worksheet_Change(ByVal Target As Range)
Const BLOCK_SIZE As Long = 20 '(+1 header)
Dim n As Long, i As Long, rngCheck As Range, c As Range, rStart As Long
Me.Unprotect 'use Me to refer to the sheet itself
Set rngCheck = Me.Range("G20") 'first cell to check
rStart = 132 'start row (header) for section 1
For i = 1 To 100
Set c = Application.Intersect(rngCheck, Target) 'Target intersects with cell being checked?
If Not c Is Nothing Then
n = c.Value
If n > BLOCK_SIZE Then n = BLOCK_SIZE 'limit number of rows to show
Me.Cells(rStart, 1).Resize(BLOCK_SIZE + 1).EntireRow.Hidden = True 'hide all
If n > 0 Then Me.Cells(rStart, 1).Resize(n + 1).EntireRow.Hidden = False 'unhide the ones we want
End If
Set rngCheck = rngCheck.Offset(1, 0) 'next cell to check
rStart = rStart + (BLOCK_SIZE + 1) 'next block starting row
Next i
End Sub
I have a sheet with 1532 rows and 7 columns called "Delayed Students". I want to make a pivot table in the sheet but every time I use my code, I get a
run-time error'438 "Object doesn't support this property or method"
And this area is yellow (.Position =1):
With .PivotFields("FACULTY_ID")
.Orientation = xlDataField
.Postion = 1
But it creates the pivot table anyways. The problem is when i delete the table and try to use the code again it doesn't create the pivot table again. So something must be wrong with my code:
Sub Pivot1()
Dim PvtTbl As PivotTable
Dim PvtCache As PivotCache
Dim PvtTblName As String
Dim pivotTableWs As Worksheet
PvtTblName = "pivotTableName"
Set pivotTableWs = Sheets("Delayed Students")
Set PvtCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:="Delayed Students!R1C1:R1532C7")
Set PvtTbl = pivotTableWs.PivotTables.Add(PivotCache:=PvtCache, TableDestination:=pivotTableWs.Range("J1"), TableName:=PvtTblName)
With PvtTbl
.ColumnGrand = True
.HasAutoFormat = True
.DisplayErrorString = False
.DisplayNullString = True
.EnableDrilldown = True
.ErrorString = ""
.MergeLabels = False
.NullString = ""
.PageFieldOrder = 2
.PageFieldWrapCount = 0
.PreserveFormatting = True
.RowGrand = True
.SaveData = True
.PrintTitles = False
.RepeatItemsOnEachPrintedPage = True
.TotalsAnnotation = False
.CompactRowIndent = 1
.InGridDropZones = False
.DisplayFieldCaptions = True
.DisplayMemberPropertyTooltips = False
.DisplayContextTooltips = True
.ShowDrillIndicators = True
.PrintDrillIndicators = False
.AllowMultipleFilters = False
.SortUsingCustomLists = True
.FieldListSortAscending = False
.ShowValuesRow = False
.CalculatedMembersInFilters = False
.RowAxisLayout xlCompactRow
With .PivotCache
.RefreshOnFileOpen = False
.MissingItemsLimit = xlMissingItemsDefault
End With
.RepeatAllLabels xlRepeatLabels
With .PivotFields("STUDYBOARD_ID")
.Orientation = xlRowField
.Position = 1
End With
With .PivotFields("FACULTY_ID")
.Orientation = xlDataField
.Postion = 1
End With
End With
End Sub
Hope someone can help me with what i am doing wrong :)
I'm having trouble adding another function in that macro I used to activate or deactivate columns in a Excel Workbook we are using at work. I'm getting the Out of stack space error when running it just adding one of the following function.
Mostly, I've used an If( ;1;0) to manage the activation part and an If(;TRUE;FALSE) for the locked/unlocked part. The function I want to had is based on the same idea using a verification code to Clearcontents of a cell and locked it. If the verification code is false, then, I want the cell to be unlocked so the user can write the value. Here is the code line I want to had times 15 as already done for the locked, unlocked function.
If Range("AS16") = "Vrai" Then
Range("AA16").ClearContents
Range("AA16").Locked = True
Else:
Range("AA16").Locked = False
End If
Here is the code I'm using right now.
Private Sub Worksheet_Change(ByVal Target As Range)
ActiveSheet.Unprotect ("Francis")
Dim Cell As Range
Set Cell = ActiveCell
Application.ScreenUpdating = False
For Each cellule In Range("S50:X50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("S50:X50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
If Range("AR16") = "Vrai" Then
Range("K16").Locked = False
Range("O16").Locked = False
Else:
Range("K16").Locked = True
Range("O16").Locked = True
End If
If Range("AR18") = "Vrai" Then
Range("K18").Locked = False
Range("O18").Locked = False
Else:
Range("K18").Locked = True
Range("O18").Locked = True
End If
If Range("AR20") = "Vrai" Then
Range("K20").Locked = False
Range("O20").Locked = False
Else:
Range("K20").Locked = True
Range("O20").Locked = True
End If
If Range("AR22") = "Vrai" Then
Range("K22").Locked = False
Range("O22").Locked = False
Else:
Range("K22").Locked = True
Range("O22").Locked = True
End If
If Range("AR24") = "Vrai" Then
Range("K24").Locked = False
Range("O24").Locked = False
Else:
Range("K24").Locked = True
Range("O24").Locked = True
End If
If Range("AR26") = "Vrai" Then
Range("K26").Locked = False
Range("O26").Locked = False
Else:
Range("K26").Locked = True
Range("O26").Locked = True
End If
If Range("AR28") = "Vrai" Then
Range("K28").Locked = False
Range("O28").Locked = False
Else:
Range("K28").Locked = True
Range("O28").Locked = True
End If
If Range("AR30") = "Vrai" Then
Range("K30").Locked = False
Range("O30").Locked = False
Else:
Range("K30").Locked = True
Range("O30").Locked = True
End If
If Range("AR32") = "Vrai" Then
Range("K32").Locked = False
Range("O32").Locked = False
Else:
Range("K32").Locked = True
Range("O32").Locked = True
End If
If Range("AR34") = "Vrai" Then
Range("K34").Locked = False
Range("O34").Locked = False
Else:
Range("K34").Locked = True
Range("O34").Locked = True
End If
If Range("AR36") = "Vrai" Then
Range("K36").Locked = False
Range("O36").Locked = False
Else:
Range("K36").Locked = True
Range("O36").Locked = True
End If
If Range("AR38") = "Vrai" Then
Range("K38").Locked = False
Range("O38").Locked = False
Else:
Range("K38").Locked = True
Range("O38").Locked = True
End If
If Range("AR40") = "Vrai" Then
Range("K40").Locked = False
Range("O40").Locked = False
Else:
Range("K40").Locked = True
Range("O40").Locked = True
End If
If Range("AR42") = "Vrai" Then
Range("K42").Locked = False
Range("O42").Locked = False
Else:
Range("K42").Locked = True
Range("O42").Locked = True
End If
If Range("AR44") = "Vrai" Then
Range("K44").Locked = False
Range("O44").Locked = False
Else:
Range("K44").Locked = True
Range("O44").Locked = True
End If
Application.ScreenUpdating = True
Application.Goto Cell
'ActiveSheet.Protect Password:="Francis"
End Sub
Thanks a lot for your help.
Have a nice day!
You typically don't want to have performance-expensive code running in that specific handler. Worksheet_Change gets invoked every time a cell changes... and that includes changing a cell's Locked property value.
So that's how you run out of stack space: your handler is modifying cells' Locked state, which triggers the Worksheet_Change event, which modifies cells' Locked state, which triggers the Worksheet_Change event, which modifies cells' Locked state, which triggers the Worksheet_Change event, which... which eventually blows the call stack.
So prevent this accidental recursion, you need to prevent Excel from firing worksheet events when you're handling one:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo CleanFail
Application.EnableEvents = False
'do stuff
CleanExit:
Application.EnableEvents = True
Exit Sub
CleanFail:
'handle errors here...
Resume CleanExit
End Sub
As for simplifying the code, that's more of a mandate for Code Review Stack Exchange, once your code works as intended.
If any C# dev is reading this, this particular situation now has an up-for-grabs issue on Rubberduck's GitHub repository: #3109 Prevent accidental recursion in Worksheet_Change and Workbook_SheetChange handlers; once that inspection is implemented, Rubberduck will be able to warn you when you handle Worksheet_Change without disabling application events.
The Out of stack error is caused by the Change event, as noted by #Mat
Try this version which also turns the events off and on
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cellule As Range, r As Long, isVrai As Boolean
ActiveSheet.Unprotect "Francis"
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cellule In Union(Range("I50:J50"), Range("S50:X50"))
With cellule
Select Case .Value2
Case "1": .EntireColumn.Hidden = False
Case "0": .EntireColumn.Hidden = True
End Select
End With
Next
For r = 16 To 44 Step 2
isVrai = (Range("AR" & r).Value2 = "Vrai")
Range("K" & r).Locked = Not isVrai
Range("O" & r).Locked = Not isVrai
If isVrai Then Range("AR" & r).ClearContents
Next
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
'ActiveSheet.Protect Password:="Francis"
End Sub
This section can be simplified:
For Each cellule In Range("S50:X50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("S50:X50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
To the following (however, note that this will unhide any non-zero values).
For Each cellule in Range("S50:X50")
cellule.EntireColumn.Hidden = (cellule.Value = "0")
Next
For Each cellule in Range("I50:J50")
cellule.EntireColumn.Hidden = (cellule.Value = "0")
Next
And this section:
If Range("AR16") = "Vrai" Then
Range("K16").Locked = False
Range("O16").Locked = False
Else:
Range("K16").Locked = True
Range("O16").Locked = True
End If
If Range("AR18") = "Vrai" Then
Range("K18").Locked = False
Range("O18").Locked = False
Else:
Range("K18").Locked = True
Range("O18").Locked = True
End If
....
Can be simplified using a loop over Range("AR16:AR44")
For Each cellule in Range("AR16:AR44") Step 2
cellule.Offset(,-33).Locked = (cellule.Value = "Vrai")
cellule.Offset(,-29).Locked = (cellule.Value = "Vrai")
Next
I have written the below code to cycle through my worksheets as a kind of slideshow to use in a sales department. The code works perfectly when I step through in debug mode, however when I run the macro it only works intermittently, occasionally getting to the selecting of the worksheets without having reactivated the screen updating application function.
Here is the code I have created so far:
Sub Runshow()
Dim ws As Worksheet
On Error GoTo exit_
Application.EnableCancelKey = xlErrorHandler
For Each ws In ThisWorkbook.Worksheets
ws.Protect
Next
Application.DisplayFullScreen = True
Application.DisplayFormulaBar = False
ActiveWindow.DisplayWorkbookTabs = False
ActiveWindow.DisplayHeadings = False
ActiveWindow.DisplayGridlines = False
ActiveWindow.DisplayHorizontalScrollBar = False
ActiveWindow.DisplayVerticalScrollBar = False
Application.Calculation = xlManual
Let y = 0
Do Until y = 80
Application.ScreenUpdating = False
Workbooks.Open("c:\users\admin\downloads\crm.xlsx").Activate
Application.Calculate
ActiveWorkbook.Close savechanges = False
Application.ScreenUpdating = True
ThisWorkbook.Activate
Let x = 0
Do Until x = 23
For Each ws In ActiveWorkbook.Worksheets
ws.Select
Application.Wait (Now + TimeValue("00:00:10"))
x = x + 1
Next
Loop
y = y + 1
Loop
exit_:
For Each ws In ThisWorkbook.Worksheets
ws.Unprotect
Next
Application.DisplayFullScreen = False
Application.DisplayFormulaBar = True
ActiveWindow.DisplayWorkbookTabs = True
ActiveWindow.DisplayGridlines = True
ActiveWindow.DisplayHorizontalScrollBar = True
ActiveWindow.DisplayVerticalScrollBar = True
Application.Calculation = xlAutomatic
End Sub
I put together some simple code that does something similar, and works well. You can build out from here - ask any questions if there's anything you don't understand.
Sub Slideshow()
Dim ws As Worksheet
PrepareView True
For Each ws In ThisWorkbook.Worksheets
ws.Activate
Application.Wait (Now + TimeValue("00:00:10"))
Next ws
PrepareView False
End Sub
Function PrepareView(status As Boolean)
If status = True Then
ActiveWindow.DisplayWorkbookTabs = False
ActiveWindow.DisplayHeadings = False
ActiveWindow.DisplayGridlines = False
ActiveWindow.DisplayHorizontalScrollBar = False
ActiveWindow.DisplayVerticalScrollBar = False
ElseIf status = False Then
Application.DisplayFullScreen = False
Application.DisplayFormulaBar = True
ActiveWindow.DisplayWorkbookTabs = True
ActiveWindow.DisplayGridlines = True
ActiveWindow.DisplayHorizontalScrollBar = True
ActiveWindow.DisplayVerticalScrollBar = True
End If
End Function
I have a excel macro that searches many values in a column and puts the data into another worksheet. However the data is scattered and need to arrange it.
Here is the macro im using
Sub Search()
Dim i As Integer, n As Integer, SearchString As String, ws As Worksheet, ws2 As Worksheet
Dim iRet As Integer
Dim strPrompt As String
Dim strTitle As String
strPrompt = "Hit OK when you wish to proceed to the next search item."
strTitle = "Next Search"
Set ws = Sheets("FINAL")
Set ws2 = Sheets("AllData")
n = ws.Range("C2").End(xlDown).Row
For i = 2 To n
SearchString = ws.Cells(i, 3).Value
With Worksheets("Query").QueryTables.Add(Connection:= _
"URL;https://www.*****.com/catalog/***.hsm?ItemNumber=" & SearchString _
, Destination:=Worksheets("Query").Range("A1"))
.Name = SearchString
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = False
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = True
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlSpecifiedTables
.WebTables = "1"
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
iRet = MsgBox(strPrompt, vbYesNo, strTitle)
If iRet = vbNo Then
End
Else
End If
Next i
End Sub
Here is how the data is being set in my sheet
I would like to have anything that starts with the following put in columns
Crosses To:
Replaces:
Crossed From:
Also, I have my .Name set to my searchString and .FieldNames set to true but they are not showing up.
The end result i would like to have is this
+---------------+--------------+--------------+--------------+
- SearchString - Sub - Sub - Sub -
+---------------+--------------+--------------+--------------+
- AR34567 - A-TY25993 - - -
- AR11160 - TS-1087 - AR11300 - D2-0099N -
+---------------+--------------+--------------+--------------+
There would be more sub column's for AR11160, just put a few in the table above to give you the idea what i want.
UPDATE
I was able to start tweaking the data as I need it. However, I can only seem to get the number i need on the same row. On the image above you see that column K has many numbers under Crossed From:. So I need to bring all those numbers too.
Please help
Sub Search2()
Dim i As Integer, n As Integer, SearchString As String
Dim shFinal As Worksheet, shQuery As Worksheet, shAllData As Worksheet
Dim iRet As Integer
Dim strPrompt As String
Dim strTitle As String
Dim m As Long, p As Long, q As Long, r As Long
Dim vSrc As Variant, vDest() As Variant
Dim r1 As Range
Dim Blank As String
strPrompt = "Hit OK when you wish to proceed to the next search item."
strTitle = "Next Search"
Set shFinal = Sheets("FINAL")
Set shQuery = Sheets("Query")
Set shAllData = Sheets("AllData")
n = shFinal.Range("C2").End(xlDown).Row
q = 1
For i = 2 To n
SearchString = shFinal.Cells(i, 3).Value
Set qt = shQuery.QueryTables.Add(Connection:= _
"URL;https://www.***.com/catalog/***.hsm?ItemNumber=" & SearchString _
, Destination:=Worksheets("Query").Range("A1"))
With qt
.Name = SearchString
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = False
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = True
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlSpecifiedTables
.WebTables = "1"
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
shAllData.Cells(q, 1) = SearchString
p = 1
Do While p < 30
If shQuery.Cells(p, 4) Like "Replaces:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
If shQuery.Cells(p, 4) Like "Crossed From:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
If shQuery.Cells(p, 4) Like "Crosses To:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
p = p + 1
Loop
iRet = MsgBox(strPrompt, vbYesNo, strTitle)
If iRet = vbNo Then
End
Else
shQuery.UsedRange.ClearContents
End If
q = q + 1
Next i
End Sub
ANOTHER UPDATE
Another Update
I know have the data being placed like i want it. Just have one issue. When a value is searched and not found i get a error on this line [.Refresh BackgroundQuery:=False]
How can i tell this code if a result is not returned skip it?
Sub Search2()
Dim i As Integer, n As Integer, SearchString As String
Dim shFinal As Worksheet, shQuery As Worksheet, shAllData As Worksheet
Dim iRet As Integer
Dim strPrompt As String
Dim strTitle As String
Dim m As Long, p As Long, q As Long, r As Long, s As Long
Dim range As range
Dim vSrc As Variant, vDest() As Variant
Dim r1 As range
strPrompt = "Hit OK when you wish to proceed to the next search item."
strTitle = "Next Search"
Set shFinal = Sheets("FINAL")
Set shQuery = Sheets("Query")
Set shAllData = Sheets("AllData")
n = shFinal.range("C2").End(xlDown).Row
q = 1
For i = 2 To n
SearchString = shFinal.Cells(i, 3).Value
Set qt = shQuery.QueryTables.Add(Connection:= _
"URL;https://www.***.com/catalog/***.hsm?ItemNumber=" & SearchString _
, Destination:=Worksheets("Query").range("A1"))
With qt
.Name = SearchString
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = False
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlOverwriteCells
.SavePassword = True
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlSpecifiedTables
.WebTables = "1"
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
shAllData.Cells(q, 1) = SearchString
p = 1
Do While p < 30
If shQuery.Cells(p, 4) Like "Replaces:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
If shQuery.Cells(p, 4) Like "Crossed From:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
If shQuery.Cells(p, 4) Like "Crosses To:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
Set range = shQuery.range("E2:E25")
For Each cell In range
If IsEmpty(cell) Then
Exit For
Else
r = p + 1
shAllData.Cells(q, r) = shQuery.Cells(r, 5)
End If
Next
p = p + 1
Loop
iRet = MsgBox(strPrompt, vbYesNo, strTitle)
If iRet = vbNo Then
shQuery.UsedRange.ClearContents
End
Else
shQuery.UsedRange.ClearContents
End If
q = q + 1
Next i
End Sub
To answer your latest updated question
I know have the data being placed like i want it. Just have one issue. When a value is searched and not found i get a error on this line [.Refresh BackgroundQuery:=False]
How can i tell this code if a result is not returned skip it?
Below is your complete code with an error handler.
I added an On Error Resume Next statement before the line .Refresh BackgroundQuery.
After that, it checks if an error has occurred:
If not it executes your code, like it does now.
If yes, then it skips your code, resets the error handler, and goes to the next i.
Sub Search2()
Dim i As Integer, n As Integer, SearchString As String
Dim shFinal As Worksheet, shQuery As Worksheet, shAllData As Worksheet
Dim iRet As Integer
Dim strPrompt As String
Dim strTitle As String
Dim m As Long, p As Long, q As Long, r As Long, s As Long
Dim range As range
Dim vSrc As Variant, vDest() As Variant
Dim r1 As range
strPrompt = "Hit OK when you wish to proceed to the next search item."
strTitle = "Next Search"
Set shFinal = Sheets("FINAL")
Set shQuery = Sheets("Query")
Set shAllData = Sheets("AllData")
n = shFinal.range("C2").End(xlDown).Row
q = 1
For i = 2 To n
SearchString = shFinal.Cells(i, 3).Value
Set qt = shQuery.QueryTables.Add(Connection:= _
"URL;https://www.***.com/catalog/***.hsm?ItemNumber=" & SearchString _
, Destination:=Worksheets("Query").range("A1"))
With qt
.Name = SearchString
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = False
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlOverwriteCells
.SavePassword = True
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlSpecifiedTables
.WebTables = "1"
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
On Error Resume Next '<-- Added line
.Refresh BackgroundQuery:=False
End With
If Err = 0 Then '<-- Added line
On Error Goto 0 '<-- Added line
shAllData.Cells(q, 1) = SearchString
p = 1
Do While p < 30
If shQuery.Cells(p, 4) Like "Replaces:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
If shQuery.Cells(p, 4) Like "Crossed From:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
If shQuery.Cells(p, 4) Like "Crosses To:*" Then shAllData.Cells(q, p) = shQuery.Cells(p, 5)
Set range = shQuery.range("E2:E25")
For Each cell In range
If IsEmpty(cell) Then
Exit For
Else
r = p + 1
shAllData.Cells(q, r) = shQuery.Cells(r, 5)
End If
Next
p = p + 1
Loop
iRet = MsgBox(strPrompt, vbYesNo, strTitle)
If iRet = vbNo Then
shQuery.UsedRange.ClearContents
End
Else
shQuery.UsedRange.ClearContents
End If
q = q + 1
End If '<-- Added line
Err = 0 '<-- Added line
Next i
End Sub