Optimizing my VBA code with a loop

jalrs

Active Member
Joined
Apr 6, 2022
Messages
300
Office Version
  1. 365
Platform
  1. Windows
Hello guys,

So on the last weeks I managed to optimize my current code with the help of Kevin9999, Mumps and Joe4. Credits to them. Currently my situation is that the code that I managed to get takes 7 clicks for each department to trigger the last action. My boss thinks this is too much, so I need help optimizing it.

1st action is regarding copying the filtered data and pasting into respective template according to the criteria.
2nd action is to save the template with a specific name, so the file can next follow as attachment with the correct name, avoiding losing the template and having to create a new one from the start.
3rd action is to send the e-mails.

I would like to know if it's possible to complete all actions through a loop, so instead of having 7 clicks for each action for each department, 3 clicks would make it, since I'm pretending to loop.

The dropbox files I'm uploading don't have any lines of code, since I created a brand new bogus information folder to share with whoever may help me.
Next you can find the code for whole process of Apoio SP department, as of now, as an example:

1st action:
VBA Code:
Sub filtroApoioSP()

    Dim wb1 As Workbook, wb2 As Workbook
    Dim ws1 As Worksheet, ws2 As Worksheet
   
    Set wb1 = ThisWorkbook
    Set wb2 = Workbooks("T_ApoioSP.xlsm")
   
    Set ws1 = wb1.Worksheets("Stock Trânsito")
    Set ws2 = wb2.Worksheets("Pendentes")
   
    ws2.UsedRange.Offset(1).ClearContents
   
    Dim lr1 As Long, lr2 As Long
   
    lr1 = ws1.Cells(Rows.Count, 1).End(3).Row
    lr2 = ws2.Cells(Rows.Count, 1).End(3).Row + 1
   
    With ws1.Range("A5:AV" & lr1)
   
        .AutoFilter 46, "Apoio SP"
        .AutoFilter 47, "Em tratamento"
        .Offset(1).Copy ws2.Cells(lr2, 1)
       
        With ws1.Range("BH6:BH" & lr1)
       
           .Copy ws2.Cells(2, 49)
          
        End With
       
        .AutoFilter
       
    End With
   
    lr2 = ws2.Cells.Find("*", , xlFormulas, , 1, 2).Row + 1
    ws2.Range("A" & lr2 & ":A1001").EntireRow.Delete
   
    wb2.Activate
   
    ws2.Activate
   
    Dim lr3 As Long
   
    lr3 = Cells(Rows.Count, "AT").End(xlUp).Row
   
    If lr3 > 1 Then
   
        Range("AY2:AY" & lr3).FormulaR1C1 = _
            "=IF(RC[-1]="""","""",VLOOKUP(RC[-1],TAB_FDB!C[-50]:C[-49],2,0))"
           
    End If
       
End Sub

2nd action:
VBA Code:
Sub copyPTApoioSP()

Dim path As String
Dim filename As String

path = "C:\Users\joafrodrigue\Desktop\prototipo\Difusao\"
filename = "ST_até31032022_Apoio SP"
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs filename:=path & filename & ".xlsx", FileFormat:=xlOpenXMLWorkbook
Application.DisplayAlerts = True

End Sub

3rd action:
VBA Code:
Sub mailptApoioSP()

Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String

Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)

strbody = "<BODY style = font-size:12pt; font-familt:Arial>" & _
"Olá equipa, <br><br> Envio este e-mail com os pendentes em questão, até à data, em anexo.<br><br>" & _
"Cumprimentos,<br>João Rodrigues"

On Error Resume Next
    With OutMail
        .To = Cells(2, 11).Value
        .CC = Cells(2, 12).Value
        .BCC = Cells(2, 13).Value
        .Subject = Cells(2, 14).Value
        .Display
        .HTMLBody = strbody & .HTMLBody
        .Attachments.Add "C:\Users\joafrodrigue\Desktop\prototipo\Difusao\ST_até31032022_Apoio SP.xlsx"
       
    End With
    On Error GoTo 0

Set OutMail = Nothing

End Sub

Here is the share folder file share
There should be two folders inside main folder called "attachments" and "finaldocname"

I think the "Instructions" Sheet is clear on what I pretend, assuming it is possible.
Macro sheets (1,2,3,4) are there because on the instructions, the source columns to copy are different within each macro as you can see on instruction sheet. All of these are located inside Stock.xlsm

Any additional information regarding the "AS-IS" code just ask.
I hope my "TO-BE" is possible.

Thanks for your attention!
 
Last edited:
Sorry, I don't think I can be much of a help on this one.

If you do a Google search on "looping in Excel VBA", you should be able to find many articles.
You may have even more luck if you try to that same search on YouTube.
If none of them seem to be what you are looking for, then you will probably need to be more specific on exactly what it is you are looking for.
 
Upvote 0

Excel Facts

Formula for Yesterday
Name Manager, New Name. Yesterday =TODAY()-1. OK. Then, use =YESTERDAY in any cell. Tomorrow could be =TODAY()+1.
Sorry, I don't think I can be much of a help on this one.

If you do a Google search on "looping in Excel VBA", you should be able to find many articles.
You may have even more luck if you try to that same search on YouTube.
If none of them seem to be what you are looking for, then you will probably need to be more specific on exactly what it is you are looking for.
Hi Joe, thanks for your answer.

I have already searched before opening this thread, that's what I usually do. But as specific as it gets, it's harder to get answers on google or youtube. That's why I come here to MrExcel. I also have accounts on other forums, but never posted there, since this was the one I came looking for help first, even tho I'm aware of cross posting rules.

Would you be able to assist me if I'm more specific or should I open a new thread and hopefully get some help there? I'm putting aside the option of loops not being in your wheelhouse, since you only refered to charts and PBI.

I'd be down to it.

Thank you Joe
 
Upvote 0
I am actually quite good with loops, it is charts and PBI (and emailing from Excel) that are not in my wheelhouse.

I am confused about how you want to use loops in this instance.
You mention wanting to perform a bunch of different actions, and appear to be asking if you can loop through them. That doesn't make much sense to me. You typically use loops to loop through reptitions of the SAME action, not working through different actions. If you have different actions, you would typically put them all in the same procedure, or have different procedures and call each one, like I provided the link for earlier.

So that is where you kind of lost me on this question. I am not quite clear what it is you seem to want to loop through (or if loops even make sense here).
 
Upvote 0
I am actually quite good with loops, it is charts and PBI (and emailing from Excel) that are not in my wheelhouse.

I am confused about how you want to use loops in this instance.
You mention wanting to perform a bunch of different actions, and appear to be asking if you can loop through them. That doesn't make much sense to me. You typically use loops to loop through reptitions of the SAME action, not working through different actions. If you have different actions, you would typically put them all in the same procedure, or have different procedures and call each one, like I provided the link for earlier.

So that is where you kind of lost me on this question. I am not quite clear what it is you seem to want to loop through (or if loops even make sense here).
Ok, so I will explain myself better.

I have four sheets addressed as "Macro X" where X = 1, 2, 3, 4 as you can see on 1st attachment.
On Macro 1, for example, I have 5 areas on column A, as you can see on 2nd attachment.
The next step, would be to locate those areas on "Stock" Sheet as 3rd attachment, column AT
Then filter according to each area with "Em tratamento" status, on the next column, as 4th attachment.
Then copy the specified range of columns, according to what "Instructions" sheet says for each "Macro X sheet" on column K, in case of Macro 1, columns A:AV + BH, as 5th attachment.
Then Open folder of Templates and paste those columns there onto each area template. All templates have the Area Name as 6th attachment.
The next step I coded, is to make a copy of the template populated and save it with a new name to a specific location.

All instructions about the current code are on sheet ("Instructions")

Current code, for "Apoio SP" Area. For other areas of macro 1, i just change the lines highlighted as comments

VBA Code:
Option Explicit
Sub filtroApoioSP()

    Dim wb1 As Workbook, wb2 As Workbook
    Dim ws1 As Worksheet, ws2 As Worksheet

    Set wb1 = ThisWorkbook
    Set wb2 = Workbooks("ST_TEMPLATE_Apoio SP.xlsx")

    Set ws1 = wb1.Worksheets("Stock")
    Set ws2 = wb2.Worksheets("Pendentes")
   
    ws2.UsedRange.Offset(1).ClearContents
   
    Dim lr1 As Long, lr2 As Long
   
    lr1 = ws1.Cells(Rows.Count, 1).End(3).Row
    lr2 = ws2.Cells(Rows.Count, 1).End(3).Row + 1
   
    With ws1.Range("A5:AV" & lr1)
   
        .AutoFilter 46, "Apoio SP" 'change accordingly
        .AutoFilter 47, "Em tratamento"
        .Offset(1).Copy ws2.Cells(lr2, 1)
       
        With ws1.Range("BH6:BH" & lr1)
       
            .Copy ws2.Cells(2, 49)
           
        End With
       
        .AutoFilter
       
    End With
   
    lr2 = ws2.Cells.Find("*", , xlFormulas, , 1, 2).Row + 1
    ws2.Range("A" & lr2 & ":A1001").EntireRow.Delete
   
    wb2.Activate
   
    ws2.Activate
   
    Dim lr3 As Long
   
    lr3 = Cells(Rows.Count, "AT").End(xlUp).Row
   
    If lr3 > 1 Then
   
        Range("AY2:AY" & lr3).FormulaR1C1 = _
            "=IF(RC[-1]="""","""",VLOOKUP(RC[-1],TAB_FDB!C[-50]:C[-49],2,0))"
           
    End If
   
    Dim mypath As String
    Dim docname As String
   
    ws2.Protect Password:="HALAFCP", _
        DrawingObjects:=True, _
        Contents:=True, _
        Scenarios:=True, _
        UserInterfaceOnly:=True, _
        AllowFormattingCells:=False, _
        AllowFormattingColumns:=False, _
        AllowFormattingRows:=False, _
        AllowInsertingColumns:=False, _
        AllowInsertingRows:=False, _
        AllowInsertingHyperlinks:=False, _
        AllowDeletingColumns:=False, _
        AllowDeletingRows:=False, _
        AllowSorting:=True, _
        AllowFiltering:=False, _
        AllowUsingPivotTables:=False
   
    mypath = "C:\Users\joafrodrigue\Desktop\share\finaldocname\"
    docname = "ST_Apoio SP" 'change accordingly
    Application.DisplayAlerts = False
    ActiveWorkbook.SaveAs Filename:=mypath & docname & ".xlsx", FileFormat:=xlOpenXMLWorkbook
    Application.DisplayAlerts = True
   
    ActiveWorkbook.Close
   
End Sub

Basically the idea here is to parameterize the macro based on cell values. If, for instance, my boss when I exit the company, has to add another area that uses the same range of copy columns as areas identified on "Macro 1" sheet, she would only have to add the Name of Area under the last one, in this case "Transportes" - See attachment 1 again please, and the macro would identify that new area and paste it accordingly to the new template, instead of having to go to the code, copy it, paste it, make the changes highlighted as comments, add the routine to the call module and then execute it.

All templates are manually created if this is important.

Another important note, should be that on the call function, I force the workbooks to open as coded, example for Macro 1 Areas:
VBA Code:
Sub chamarmacro1()

Application.ScreenUpdating = False

Workbooks.Open Filename:="C:\Users\joafrodrigue\Desktop\share\templates/ST_TEMPLATE_Apoio SP.xlsx"
Workbooks.Open Filename:="C:\Users\joafrodrigue\Desktop\share\templates/ST_TEMPLATE_Armazém.xlsx"
Workbooks.Open Filename:="C:\Users\joafrodrigue\Desktop\share\templates/ST_TEMPLATE_PósVenda.xlsx"
Workbooks.Open Filename:="C:\Users\joafrodrigue\Desktop\share\templates/ST_TEMPLATE_SolEmpresariais.xlsx"
Workbooks.Open Filename:="C:\Users\joafrodrigue\Desktop\share\templates/ST_TEMPLATE_Transportes.xlsx"

Call filtroApoioSP
Call filtroArmazem
Call filtroPosVenda
Call filtroSolEmp
Call filtroTransportes

Application.ScreenUpdating = True

End Sub

I even proposed myself to make an instructions manual, to help those changes being easy to make, but got denied.

I know you can only open files through dropbox, since your company doesnt allow you to download from third party websites, so if it's clear now, I will upload it.

Thanks Joe! Hope you can help me sort this out
 

Attachments

  • 1.png
    1.png
    3.3 KB · Views: 10
  • 2.png
    2.png
    2.5 KB · Views: 8
  • 3.png
    3.png
    7.1 KB · Views: 5
  • 4.png
    4.png
    5.8 KB · Views: 5
  • 5.png
    5.png
    3.5 KB · Views: 7
  • 6.png
    6.png
    17 KB · Views: 9
Upvote 0
Another important note, should be that on the call function, I force the workbooks to open as coded, example for Macro 1 Areas:
I only mentioned this, because on the loop, I think this information has to be inside the loop, so we don't need to call for anything.

Thanks
 
Upvote 0
OK, it looks like you have a rather large, involved process going on here, and it is easy for us to "not see the forest for the trees" (if you are not familiar with that expression, it means that there is so much detail out there, that it gets overwhelming, and the real question gets lost in all the extra information).

We want to strip off all the extra unnecessary information, and just get down to your question.
What EXACTLY is it that you are trying to loop through?
Files?
Sheets?
Ranges?
 
Upvote 0
OK, it looks like you have a rather large, involved process going on here, and it is easy for us to "not see the forest for the trees" (if you are not familiar with that expression, it means that there is so much detail out there, that it gets overwhelming, and the real question gets lost in all the extra information).

We want to strip off all the extra unnecessary information, and just get down to your question.
What EXACTLY is it that you are trying to loop through?
Files?
Sheets?
Ranges?
Hello Joe, thanks for keeping with me.

Indeed, and it is giving me a hell of a headache. I'm new to VBA, I'm in this project for a month, and that's when I had my first touch with VBA, from the basic, setting up the "developer" tab. Just so you understand better why I have troubles explaining myself.

I would say we want to loop through column AT for macros 1 and 2, and column AU for macro 3 and 4 no? It's where the key filters are.

On popular language it would be something like this, might be better to explain myself like this:

"For each area that appears on column A, on macro 1 sheet, go to stock sheet, filter for those areas according to the columns specified on instruction sheet, column K, for the macro 1 areas, and paste the information in each templated workbook, protect it, copy it, then save the workbook with "ST_&AreaName&" on C:\Users\joafrodrigue\Desktop\share\finaldocname\ so I don't lose my template" and loop it for each area, until column A cell from macro 1 is empty, in this case after transportes, in case we have a new area, after that area. I think you follow the idea

I could then adapt the code for the other macro sheets I believe.

Thanks Joe!
 
Upvote 0
OK, here is a simple example which shows you how to find the last row with data in column AT, and loop through all the rows in that column starting from row 2 down to the end.
You can put anything you want in the middle of your loop (i.e. calling your macros to run).
In my simple example, I just have a message box returning the row number and value in column AT of that row.
VBA Code:
Sub MyTest()

    Dim lr As Long
    Dim r As Long
    
    Application.ScreenUpdating = False
    
'   Find last row with data in column AT
    lr = Cells(Rows.Count, "AT").End(xlUp).Row
    
'   Loop through all rows in column AT starting at row 2
    For r = 2 To lr
'       Return value from column AT from that row
        MsgBox "The value on row " & r & " is " & Cells(r, "AT").Value
    Next r

    Application.ScreenUpdating = True

End Sub
Is that loop structure kind of what you are looking for?
 
Upvote 0
OK, here is a simple example which shows you how to find the last row with data in column AT, and loop through all the rows in that column starting from row 2 down to the end.
You can put anything you want in the middle of your loop (i.e. calling your macros to run).
In my simple example, I just have a message box returning the row number and value in column AT of that row.
VBA Code:
Sub MyTest()

    Dim lr As Long
    Dim r As Long
  
    Application.ScreenUpdating = False
  
'   Find last row with data in column AT
    lr = Cells(Rows.Count, "AT").End(xlUp).Row
  
'   Loop through all rows in column AT starting at row 2
    For r = 2 To lr
'       Return value from column AT from that row
        MsgBox "The value on row " & r & " is " & Cells(r, "AT").Value
    Next r

    Application.ScreenUpdating = True

End Sub
Is that loop structure kind of what you are looking for?
Assuming this is the loop for macro 1 sheet. (What defines where each area will be placed, I mean, macros 1-4, is the columns range to copy and paste if it wasn't clear, it would be with the data file)

On macro 1 I have 5 Areas at the moment: Apoio SP, Armazém, Pós Venda, SolEmpresariais and Transportes. The company can have more in the future, that's why they want to parameterize the code based on cell values, instead of being "locked" to a code.

Inside the loop of macro 1 we would have: for each area, filter with AreaName, force ST_Template_AreaName to open, filter with status "Em tratamento", copy range of columns, paste range of columns to ST_Template_AreaName, protect it, make a copy, saveas ST_AreaName at location C:\..\...\...

Then I would adapt it to the other macro sheets, should be easy to understand the code and reproduce it applying the needed changes.

Note that I don't want to make you lose time, I would find it better to send you the dropbox file, and when you got the time to look to it, you would do, as you said I have "rather large, involved process".

The bogus data sample I work was made following the rules you told me to when you helped me with the vlookup formula thread

Answering your question, I believe that is a start. Column AT on "Stock" sheet, will always be populated as you coded

Thanks Joe, tell me something regarding the dropbox file.
 
Upvote 0
Unfortunately, I do not have the ability to download any files from my current location. That being said, I have a feeling that will only overcomplicate matters (where I keep imploring you to simplify things). You should be able to ask very specific, pointed questions.

I almost get the impression that you are looking something more like a consultant, someone to kind of advise you and help you work through this whole project. That is really not what this forum was designed for (not is it designed to "teach" people broad subjects like VBA). It is not meant to take the place of consultants or Excel/VBA courses, it is designed to deal with very pointed, specific Excel/VBA questions.

If you are looking to go the Consulting route, while we don't offer consulting services directly, there are people we can suggest, as noted here: Consulting Services

A notes on my previous code.
- It can be applied to any sheet by either selecting that sheet at the top of the code, or by using/setting sheet references in your code (see: VBA Guide To Referencing Worksheet Tabs — TheSpreadsheetGuru). You can even set up an array of sheet names and loop through them.
- Note that my code is "dynamic". It finds the last row in column AT at the time it runs. So if that ending spot changes, it is not a problem for the code since it dynamically finds the ending when it runs.

You can also set up your procedures to take in parameters (since you mentiond that).
See: Calling Sub and Function procedures (VBA)
 
Upvote 0

Forum statistics

Threads
1,223,231
Messages
6,170,884
Members
452,364
Latest member
springate

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