Looping through sheets and retrieving data from specific cells

Alemap

New Member
Joined
Dec 29, 2019
Messages
30
Office Version
  1. 2010
Platform
  1. Windows
Good Day everyone, I'm trying to loop through many sheets in a workbook and retrieve data from a table array of size A54:AD73 on a particular date and post the values into a table array in a results sheet. (see table below)
The values to be collected against a Name, which is in cell C1 of every sheet, will be in columns Y to AD in the row with the date, which could be in different rows for each sheet. The date if it has been entered, resides in Column B of every sheet.

1577614507831.png

I Have being trying to combine code that I already have that loops through all sheets and retrieves summary data from the same cells of each sheet.

The code below runs but it only retrieves data from row B54 in which I entered the date for each sheet for testing but am unable to proceed with looping throgh the sheets, match the date and post the data in the results sheet

[VBA Code]
Sub MonthlyMedal()


ActiveSheet.Unprotect Password:="xxxx"
Dim i As Long
Dim j As Long
Dim MatchDay As Date
Dim Lastrow As Long

Dim wksMonthlyMedal As Worksheet
Dim wksCurr As Worksheet
Dim arrData() As Variant
Dim intRow As Integer
'MatchDay = InputBox("Match Date Is")
MatchDay = "19/01/19"


intRow = 0
ReDim arrData(1 To ThisWorkbook.Worksheets.Count - 1, 1 To 7)

Set wksResults = ThisWorkbook.Worksheets("Results")
Set wksLady_Players = ThisWorkbook.Worksheets("Lady_Players")
Set wksSurvey = ThisWorkbook.Worksheets("Survey")
Set wksTemplate = ThisWorkbook.Worksheets("Template")
Set wksMonthlyMedal = ThisWorkbook.Worksheets("MonthlyMedal")

Dim screenUpdateState
Dim calcState
Dim eventsState

'check functionality status

screenUpdateState = Application.ScreenUpdating
calcState = Application.Calculation
eventsState = Application.EnableEvents

'turn off screen updating to stop flicker & increase speed
'turn off automatic recalculating mode
'turn off events processing

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False



For Each wksCurr In ThisWorkbook.Worksheets

If wksCurr.Name <> wksResults.Name _
And wksCurr.Name <> wksLady_Players.Name _
And wksCurr.Name <> wksSurvey.Name _
And wksCurr.Name <> wksMonthlyMedal.Name _
And wksCurr.Name <> wksTemplate.Name Then


'For j = 54 To 56
' If wksCurr.Range(j, "B") = MatchDay Then
' MsgBox ActiveWorkbook.Worksheets(i).Cells(j, "B").Value
' MsgBox wksCurr.Range(j, "B").Value
' Next
'Lastrow = Lastrow + 1
'End If
'
intRow = intRow + 1
arrData(intRow, 1) = wksCurr.Range("C1") 'B Name
arrData(intRow, 2) = wksCurr.Range("Y54") 'C Score 1
arrData(intRow, 3) = wksCurr.Range("Z54") 'D Score 2
arrData(intRow, 4) = wksCurr.Range("AA54")'E Score 3
arrData(intRow, 5) = wksCurr.Range("AB54") 'F Score 4
arrData(intRow, 6) = wksCurr.Range("AC54") 'G Putts
arrData(intRow, 7) = wksCurr.Range("AD54") 'H Division
'

End If
Next wksCurr
wksMonthlyMedal.Range("B5").Resize(UBound(arrData), UBound(arrData, 2)) = arrData
Set wksCurr = Nothing
Set wksMonthlyMedal = Nothing

Application.ScreenUpdating = screenUpdateState
Application.Calculation = calcState
Application.EnableEvents = eventsState
ActiveSheet.Protect Password:="7410", DrawingObjects:=True, Contents:=True, Scenarios:=True


End Sub [/Code]
 
I think I solved this puzzle (if so, then it's my first contribution in the MMXX decade on this board, at least where I live). Working with different Worksheet objects and Range objects can be rather difficult (in the past I've had much problems with it). Anyway, a made a few justifications to jasonb75 initial code, for the most significant part see below. The code takes action on the active worksheet (this can be changed), on which easily a FormButton can be placed; @Alemap I understand you can manage that yourself. If not, let me know. The code will not clear anything, however, overwriting it does. I've also added a dialog with some input checking just for convenience (and some unnecessary fun parts; btw "woensdag" will be Wednesday, my local system is Dutch).

View attachment 2996View attachment 2997

This resulted in two modules, a regular one and a userform. Both depend on each other. The regular one consists of two procedures, one to launch the dialog and one to do the job as desired. Although the userform code is also on the board here, you can't use it. An existing userform consists of two files; one in ASCII and one in (kind of) binary. So the userform has to be imported. This can be done by right clicking on the project name in the left pane in the VBA editor; choose import file on the pop-up. Btw, the import dialog will show you just one of the two files: the .frm file will be seen but the .frx file is also needed (do not change filenames before importing). To be sure, make a copy of your scores workbook and import the two modules in that copy.



Both modules can be downloaded here WeTransfer

GWteB thank you so much for your input. I have looked at the code, downloaded it, but have not run it in the Monthly Medal sheet yet - to be honest it looks too complicated for me and quite involved? I have not had experience with User forms yet but I use Form Control buttons extensively and Drop-down lists . I was thinking of including a drop down list to select the date because these dates are actually pre-determined - the dates of the matches has been set a long time in advance so that I think a Drop-down list would work well, as it could validate the entry to prevent an error in the input???
 
Upvote 0

Excel Facts

Excel Joke
Why can't spreadsheets drive cars? They crash too often!
I enter the date in the MsgBox and then follow the code with 'F8" and it completes 12 or 13 iterations and arrives at the snip below.
That sounds like it's excluding every sheet without getting as far as checking the dates. Running correctly, there should be 1 iteration per sheet plus 20 iterations for each sheet that is not excluded.

To identify or eliminate this as the cause before changing anything else, I've added 2 messagebox lines to the code below, for each iteration of the code you should see one to tell you if the sheet is being searched or ignored and the name of that sheet.

If the sheets are being identified as searched or ignored correctly then that would mean that the problem lies in the line, If c = MatchDay Then. I've made a slight change to this line for now but don't want to change too much until we identify the actual problem point.

VBA Code:
Option Explicit
Sub MonthlyMedal()
With ActiveSheet
    .Unprotect Password:="xxxx" ' remove protection
Dim MatchDay As Date, calcState As Long, wksCurr As Worksheet, c As Range, rCount As Long
MatchDay = InputBox("Match Date Is") 'set date, anything that is not a valid date could cause an error
With Application
    calcState = .Calculation ' turn a few things off to speed things up a bit
    .ScreenUpdating = False
    .Calculation = xlCalculationManual
    .EnableEvents = False
End With

For Each wksCurr In ThisWorkbook.Worksheets ' loop through worksheets exlude any listed in the line below
    If Not (CBool(InStr(LCase("|Results|Lady_Players|Survey|Template|MonthlyMedal|"), LCase("|" & .Name & "|")))) Then
        MsgBox "Searching " & wksCurr.Name
        For Each c In wksCurr.Range("B54:B73") ' loop through dates in column B
            If CLng(c) = CLng(MatchDay) Then ' matchday found
                .Range("B6").Offset(rCount) = wksCurr.Range("C1") ' copy name
                .Range("C6:H6").Offset(rCount) = Intersect(c.EntireRow, wksCurr.Range("Y:AD")) ' copy score data
                .Range("K6").Offset(rCount) = wksCurr.Name & " " & c.Address(0, 0) ' this line for testing only, identify where data found.
                rCount = rCount + 1 ' keep a count of how many rows have been added
            End If
        Next c
    Else
        MsgBox wksCurr.Name & " Not Searched"
    End If
Next wksCurr
    .Range("B3") = MatchDay ' enter matchday date into B3
With Application
    .ScreenUpdating = True ' turn things back on again
    .Calculation = calcState
    .EnableEvents = True
End With
    .Protect Password:="xxxx" ' re-protect sheet
End With
End Sub

One thought, are the scorecards the result of copy and paste from an external source? It is not uncommon for hidden characters to cause problems, particularly with data copied from web pages.
 
Upvote 0
That sounds like it's excluding every sheet without getting as far as checking the dates. Running correctly, there should be 1 iteration per sheet plus 20 iterations for each sheet that is not excluded.

To identify or eliminate this as the cause before changing anything else, I've added 2 messagebox lines to the code below, for each iteration of the code you should see one to tell you if the sheet is being searched or ignored and the name of that sheet.

If the sheets are being identified as searched or ignored correctly then that would mean that the problem lies in the line, If c = MatchDay Then. I've made a slight change to this line for now but don't want to change too much until we identify the actual problem point.

VBA Code:
Option Explicit
Sub MonthlyMedal()
With ActiveSheet
    .Unprotect Password:="xxxx" ' remove protection
Dim MatchDay As Date, calcState As Long, wksCurr As Worksheet, c As Range, rCount As Long
MatchDay = InputBox("Match Date Is") 'set date, anything that is not a valid date could cause an error
With Application
    calcState = .Calculation ' turn a few things off to speed things up a bit
    .ScreenUpdating = False
    .Calculation = xlCalculationManual
    .EnableEvents = False
End With

For Each wksCurr In ThisWorkbook.Worksheets ' loop through worksheets exlude any listed in the line below
    If Not (CBool(InStr(LCase("|Results|Lady_Players|Survey|Template|MonthlyMedal|"), LCase("|" & .Name & "|")))) Then
        MsgBox "Searching " & wksCurr.Name
        For Each c In wksCurr.Range("B54:B73") ' loop through dates in column B
            If CLng(c) = CLng(MatchDay) Then ' matchday found
                .Range("B6").Offset(rCount) = wksCurr.Range("C1") ' copy name
                .Range("C6:H6").Offset(rCount) = Intersect(c.EntireRow, wksCurr.Range("Y:AD")) ' copy score data
                .Range("K6").Offset(rCount) = wksCurr.Name & " " & c.Address(0, 0) ' this line for testing only, identify where data found.
                rCount = rCount + 1 ' keep a count of how many rows have been added
            End If
        Next c
    Else
        MsgBox wksCurr.Name & " Not Searched"
    End If
Next wksCurr
    .Range("B3") = MatchDay ' enter matchday date into B3
With Application
    .ScreenUpdating = True ' turn things back on again
    .Calculation = calcState
    .EnableEvents = True
End With
    .Protect Password:="xxxx" ' re-protect sheet
End With
End Sub

One thought, are the scorecards the result of copy and paste from an external source? It is not uncommon for hidden characters to cause problems, particularly with data copied from web pages.

OK jasonb75, first up - your message box comes up with none of the worksheets being searched. None of the 12 sheets have been searched , and the program returns to the beginning!
Again only the date is entered and is correct.

The score cards are not copied and pasted they are captured (entered) by hand from the actual cards.
I hope this is not spoiling your new year??
 
Upvote 0
Added an extra line which will enter then name of the sheet and the cell where the date was found into column K of the results table to assist with testing.

Oh jasonb75, I omitted to mention also that your new column K display any contents.
 
Upvote 0
GWteB thank you so much for your input. I have looked at the code, downloaded it, but have not run it in the Monthly Medal sheet yet - to be honest it looks too complicated for me and quite involved? I have not had experience with User forms yet but I use Form Control buttons extensively and Drop-down lists . I was thinking of including a drop down list to select the date because these dates are actually pre-determined - the dates of the matches has been set a long time in advance so that I think a Drop-down list would work well, as it could validate the entry to prevent an error in the input???
You're welcome and thanks for the feedback! (y)

In your approach you are managing all the jobs in one single code procedure. I've been splitting up some things. It makes maintenance more easy and it's more according to how the OS Windows (internally) works (to prevent mysterious, sometimes inexplicable behaviors). Anyway, my code is rather less complicated than it appears. Perhaps I could have done some more explanation, I do this now.

The dialog I made (in the Userform module) is only designed for user input to get a valid date. Day/month/year can be entered manually or by using de dropdowns (for example, the month dropdown lists from 1 to 12). When manually (by mistake) a non number character is entered, the code doesn't crash. Also it doesn't confront the user with annoying pop-ups or message boxes, it just checks on validity (e.g. February, 31th doesn't exist) and offers the user to correct his/hers input. When the "GO" button is pressed, the ExtractScores procedure in the regular module is called.

To be able to perform, the ExtractScores procedure needs three parameters:
1. the calling object (i.e the "get date dialog" on the Userform to interact with in order to inform the dialog about progress and to offer the opportunity to abort);
2. the worksheet to place the scores on;
3. the requested date to search for.
Regarding the source/destination sheets, if layout changes only this ExtractScores procedure needs to be modified.

Because the ExtractScores procedure needs to be informed (by its caller) on which sheet to place data on (2nd parameter), the "get date dialog" also needs to be informed. After all this dialog calls the ExtractScores procedure with the GO button. Exactly that (informing) is done by the line of code
VBA Code:
usfMulti.SetScoreDestination ThisWorkbook.ActiveSheet
in the LaunchSearchAndExtract procedure (regular module). By calling this "method" of the usfMulti object, the dialog is properly informed before it appears on the screen with the Show method. Thereafter the dialog is just waiting for user input and can always be aborted.
 
Upvote 0
To stay with your original and slightly modified code, I've the following remarks.
The .Name property in the IF NOT line (to exlude some worksheets) is pulled from the wrong Worksheet object.
Also the Intersect method may manipulate ranges in a way, that the .Value property isn't always the default.
Changing the following lines of code may have a result as expected.

Change
VBA Code:
If Not (CBool(InStr(LCase("|Results|Lady_Players|Survey|Template|MonthlyMedal|"), LCase("|" &        .Name & "|")))) Then
in
VBA Code:
If Not (CBool(InStr(LCase("|Results|Lady_Players|Survey|Template|MonthlyMedal|"), LCase("|" & wksCurr.Name & "|")))) Then


Change
VBA Code:
.Range("C6:H6").Offset(rCount) = Intersect(c.EntireRow, wksCurr.Range("Y:AD"))         ' copy score data
in
VBA Code:
.Range("C6:H6").Offset(rCount) = Intersect(c.EntireRow, wksCurr.Range("Y:AD")).Value      ' copy score data


Kind regards,
 
Upvote 0
VBA Code:
If Not (CBool(InStr(LCase("|Results|Lady_Players|Survey|Template|MonthlyMedal|"), LCase("|" & .Name & "|")))) Then
That's the error that I was missing, name check on the wrong sheet :oops:
VBA Code:
Option Explicit
Sub MonthlyMedal()
With ActiveSheet
    .Unprotect Password:="xxxx" ' remove protection
Dim MatchDay As Date, calcState As Long, wksCurr As Worksheet, c As Range, rCount As Long
MatchDay = InputBox("Match Date Is") 'set date, anything that is not a valid date could cause an error
With Application
    calcState = .Calculation ' turn a few things off to speed things up a bit
    .ScreenUpdating = False
    .Calculation = xlCalculationManual
    .EnableEvents = False
End With

For Each wksCurr In ThisWorkbook.Worksheets ' loop through worksheets exlude any listed in the line below
    If Not (CBool(InStr(LCase("|Results|Lady_Players|Survey|Template|MonthlyMedal|"), LCase("|" & wksCurr.Name & "|")))) Then
        For Each c In wksCurr.Range("B54:B73") ' loop through dates in column B
            If c = MatchDay Then ' matchday found
                .Range("B6").Offset(rCount) = wksCurr.Range("C1") ' copy name
                .Range("C6:H6").Offset(rCount) = Intersect(c.EntireRow, wksCurr.Range("Y:AD")) ' copy score data
                .Range("K6").Offset(rCount) = wksCurr.Name & " " & c.Address(0, 0) ' this line for testing only, identify where data found.
                rCount = rCount + 1 ' keep a count of how many rows have been added
            End If
        Next c
    End If
Next wksCurr
    .Range("B3") = MatchDay ' enter matchday date into B3
With Application
    .ScreenUpdating = True ' turn things back on again
    .Calculation = calcState
    .EnableEvents = True
End With
    .Protect Password:="xxxx" ' re-protect sheet
End With
End Sub
Now as long as there are no issues with the date formats matching then all should be good.
 
Upvote 0
Now as long as there are no issues with the date formats matching then all should be good.
Yes, it is! I have tested it all (both, yours and mine ;)). HAPPY NEW YEAR!
 
Upvote 0
Sorry jasonB75 , the date is collected and inserted in the correct format, the Names are collected and inserted in column B and your new column K has come out correctly - But I'm afraid the values in columns Y:AD have not been collected and inserted in the table. Frustrating I know but very close now. Thank you for all your trouble.
 
Upvote 0
Have you tried it with and without GWteB's second suggestion of adding .Value to the end of the line that copies Y:AD?
 
Upvote 0

Forum statistics

Threads
1,215,472
Messages
6,125,009
Members
449,204
Latest member
tungnmqn90

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top