Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

Extract data based on sheet name & two dates

0

Hello

I have project to extract data if I write the sheet name in G2 then will populate data and insert total row to sum the amounts , if I write the sheet name in G2   and two dates in C2,E2 then will populate data for sheet name within two dates . so far is ok , but there is problem if I write dates in C2=25/05/2023,E2=25/05/2023 I expect populate data for date(25/05/2023) ,also if I write dates in C2=25/05/2023 ,E2=27/05/2023 I expect populate data for date(25/05/2023) becuase there is no date 27/05/2023 

but both cases will show mismatch error in this line

.Offset(, 1).Resize(UBound(a) + 1, 3) = Application.Index(b, Application.Transpose(a), [{2,4,10}])

any way to fix this problem,please?

thanks

Answer
Discuss

Discussion

Hh

Kalil. I'll look again tomorrow but I took a very quick look at your file before I left home (2 hours ago). With the same dates in C2 and E2 plus BUYING, I seem to recall that a was a single element "5". << REVISED 11 March 2024 to delete confusing commnet by me! >>)
John_Ru (rep: 6142) Mar 10, '24 at 11:39 am
@John,
I too gave this a quick look but decided to pass for the following reasons. The command button “EXTRACT” on sheet “SH2” is assigned macro “test3” but that macro is not part of this workbook. The archaic variable declarations: suffix “$” for string type, “&” for long type, etc. Variables “a” and “b” not declared. After declaring "a" and "b" as “Long” then “UBound” faults with a compile error “Expected array”. I will leave this to you to repair (if you chose)  
Cheers   :-)
WillieD24 (rep: 557) Mar 10, '24 at 10:06 pm
Your Index function has an array with just 3 elements so VBA wouldn't find that 5th entry.
yes , I thought no need adding more elements to fix my problem .
the idea should deal with dates cells as long indicate that !
Kalil (rep: 36) Mar 11, '24 at 4:11 am
@Kalil - please see my Answer

@Willie - thanks. I didn't declare a and b as Long like you did but created a workaround solution.
John_Ru (rep: 6142) Mar 11, '24 at 8:13 am
Add to Discussion

Answers

0
Selected Answer

Kalil

The problem occurs when your (undeclared) variable a is a single element array (i.e. if there's just one Total in the filtered date range). Using Transpose to determine the second (row_num) argument of the Index worksheet function (in the line cited in your Question) causes VBA to fail.

In the attached modified file, the button is relabelled "Extract" and assigned to the module procedure test below. Data validation is added to G" (to make sheet selection easier and avoid error if typed incorrectly)

That code is modified to cater for when a covers several totals or there's just one. A new variable RwNum is used to do that. Also it allows for when no totals are found. See changes and comments in bold below:

Sub test()

    Dim ws As Worksheet, ShName$, DateFrom&, DateTo&
    Dim a As Variant, b As Variant, RwNum As Variant

    Set ws = Sheets("SH2")
    ShName = ws.[G2]
    DateFrom = ws.[C2]
    DateTo = ws.[E2]

    If ShName = "" And DateFrom = 0 And DateTo = 0 Then
        ws.[A4].CurrentRegion.Offset(1).Clear
        Exit Sub
    End If

    With Sheets(ShName).[A1].CurrentRegion.Columns(1)
        If DateFrom = 0 Or DateTo = 0 Then
            a = Filter(.Parent.Evaluate(Replace("transpose(if(@=""Total"",row(@),0))", "@", .Address)), 0, 0)
        Else
            a = Filter(.Parent.Evaluate(Replace("transpose(if(((@)=""Total"")*(offset(@,,1)>=" & DateFrom & ")*(offset(@,,1)<=" & DateTo & "),row(@),0))", "@", .Address)), 0, 0)
        End If

        If UBound(a) < 0 Then
        ' if no records, say and quit
            MsgBox "No records in that date range for sheet " & ShName
            Exit Sub
        End If

        ' otherwise determine RwNum dependent on the number of Totals
        If UBound(a) > 0 Then
            ' if more than 1, create an array
            RwNum = Application.Transpose(a)
            Else
            ' if there's one, make it that value
            RwNum = a(0)
        End If

        b = .Parent.[A1].CurrentRegion.Value
    End With

    With ws
        .[A4].CurrentRegion.Offset(1).Clear
        With .Range("A" & Rows.Count).End(3)(2)
            ' use RwNum as second argument of Index
            .Offset(, 1).Resize(UBound(a) + 1, 3) = Application.Index(b, RwNum, [{2,4,10}])
            .Resize(UBound(a) + 1) = Evaluate("row(1:" & UBound(a) + 1 & ")")
        End With
        With .Range("A" & Rows.Count).End(3)(2)
            .Value = "Total"
            .Offset(, 3) = "=sum(d5:d" & .Row - 1 & ")"
            With .CurrentRegion
                .Borders.LineStyle = 1
                .HorizontalAlignment = xlCenter
                .Columns(4).NumberFormat = "#,0.00"
            End With
        End With
    End With

End Sub

The code should now work well in all cases. If so, please remember to mark this Answer as Selected.

Note: other users of this Forum may be puzzled by lines like:

        With .Range("A" & Rows.Count).End(3)(2)

.Note that the portion .Range("A" & Rows.Count).End(3) equates to the perhaps more familiar:

Range("A" & Rows.Count).End(xlUp)

so a range equal to the last used cell in column A and the additional (2) gives the "second" row from that range i.e. the cell BELOW the last used one, and so equivalent to:

        With .Range("A" & Rows.Count).End(xlUp).Offset(1,0))
Discuss

Discussion

awesome !
thank you so much ,John.
Kalil (rep: 36) Mar 11, '24 at 2:01 pm
Glad that helped. Thanks for selecting my Answer, Kalil. 
John_Ru (rep: 6142) Mar 11, '24 at 2:53 pm
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login