How to avoid using .Select, .Activate, ActiveSheet,ActiveCell in my specific vba code?

后端 未结 3 1927
被撕碎了的回忆
被撕碎了的回忆 2020-12-20 10:49

I have this code that obviously use Select, .Activate,...and I understand it\'s not a good practice in addition the application is craching now and then so thats probably be

相关标签:
3条回答
  • 2020-12-20 11:06

    Whenever you have to scroll horizontally to read your code; consider refactoring.

    If you have a Range reference that contains two Cell references that share variables it would probably be better to use Range Resize.

    Both of these examples are referring to the same Range. Using Range Resize we are able to remove shared variable.

    Range(Cells(a + b, c), Cells(a + b + 10, c + 10))

    Cells(a + b, c).Resize(10 + 1, 10 + 1)

    Note: You will have to add one to the Columns and Rows parameter.

    Option Explicit
    
    Sub FormatText()
        Dim bc As Long, br As Long, pr As Long
    
        bc = BoxColOffset(Box)
        br = BoxRowOffset(Box)
        pr = PageRowOffset(Page)
    
        With Worksheets("A4")
            With .Cells(1 + pr + br - 2, bc).Font
                .Name = "Calibri"
                .Size = 11
                .Underline = xlUnderlineStyleNone
                .ThemeColor = xlThemeColorLight1
                .TintAndShade = 0
                .ThemeFont = xlThemeFontMinor
                .Bold = False
            End With
        End With
    
        With Worksheets("Sheet1")
            With .Cells(pr + br, 1 + bc).Resize(4, 2).Font
                .Name = "Calibri"
                .Size = 8
                .Strikethrough = False
                .Superscript = False
                .Subscript = False
                .OutlineFont = False
                .Shadow = False
                .Underline = xlUnderlineStyleNone
                .TintAndShade = 0
                .ThemeFont = xlThemeFontMinor
                .Bold = False
            End With
    
            With .Cells(pr + br + 4, 1 + bc).Resize(4, 2).Font
                .Name = "Calibri"
                .Size = 7
                .Strikethrough = False
                .Superscript = False
                .Subscript = False
                .OutlineFont = False
                .Shadow = False
                .Underline = xlUnderlineStyleNone
                .TintAndShade = 0
                .ThemeFont = xlThemeFontMinor
                .Bold = False
            End With
    
            With .Cells(1 + pr + br + 1, 1 + bc + 1).Resize(2)
                .NumberFormat = "#,##0.00"
                .HorizontalAlignment = xlGeneral
                .VerticalAlignment = xlTop
                .WrapText = False
                .Orientation = 0
                .AddIndent = False
                .IndentLevel = 0
                .ShrinkToFit = False
                .ReadingOrder = xlContext
                .MergeCells = False
            End With
        End With
    
    
        'Updated to answer:'**How do you attack something like this?**
        With Worksheets("report")
            If fcnHasImage(.Cells(15 + i, 24)) Then
                .Cells(15 + i, 24).CopyPicture
            Else
                .Cells(15 + i, 2).CopyPicture
            End If
    
            Sheets("A4").Cells(1 + pr + br + 7, bc + 1).PasteSpecial
    
            ShowProgress    'Run macro
            .Cells(1, 25).Value = 15 + i
        End With
    
    End Sub
    
    0 讨论(0)
  • 2020-12-20 11:10

    The below is a shortened-up version of your code:

    Sub FormatText()
    
        With Sheets("A4").Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) - 2, BoxColOffset(Box)).Font
            .Name = "Calibri"
            .Size = 11
            .Underline = xlUnderlineStyleNone
            .ThemeColor = xlThemeColorLight1
            .ThemeFont = xlThemeFontMinor
        End With
    
    
    
        With Range(Cells(PageRowOffset(Page) + BoxRowOffset(Box), 1 + BoxColOffset(Box)), Cells(PageRowOffset(Page) + BoxRowOffset(Box) + 3, 1 + BoxColOffset(Box) + 1)).Font
            .Name = "Calibri"
            .Size = 8
            .Underline = xlUnderlineStyleNone
            .ThemeFont = xlThemeFontMinor
        End With
    
        With Range(Cells(PageRowOffset(Page) + BoxRowOffset(Box) + 4, 1 + BoxColOffset(Box)), Cells(PageRowOffset(Page) + BoxRowOffset(Box) + 7, 1 + BoxColOffset(Box) + 1)).Font
            .Name = "Calibri"
            .Size = 7
            .Underline = xlUnderlineStyleNone
            .ThemeFont = xlThemeFontMinor
        End With
    
        Range(Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) + 1, 1 + BoxColOffset(Box) + 1), Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) + 2, 1 + BoxColOffset(Box) + 1)).NumberFormat = "#,##0.00"
        With Range(Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) + 1, 1 + BoxColOffset(Box) + 1), Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) + 2, 1 + BoxColOffset(Box) + 1))
            .HorizontalAlignment = xlGeneral
            .VerticalAlignment = xlTop
            .ReadingOrder = xlContext
        End With
    End Sub
    
    0 讨论(0)
  • 2020-12-20 11:18

    Select and Activate are basically just methods that are used in recording macros. To trim down a macro from there, you can do the following:

    • Anywhere ActiveCell is used, simply replace it with the Range reference that .Activate was called on. (In your case, the first With ActiveCell.Font would become With Sheets("A4").Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) - 2, BoxColOffset(Box)).Font)
    • Anywhere Selection is used, simply replace it with the Range reference that .Select was called on. (In your case, With Selection would become With Range(Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) + 1, 1 + BoxColOffset(Box) + 1), Cells(1 + PageRowOffset(Page) + BoxRowOffset(Box) + 2, 1 + BoxColOffset(Box) + 1)))

    As an aside, when you correct that last With Selection block, you'll be able to move the .NumberFormat adjustment into the With block as well.

    Some additional advice would be to get in the habit of establishing Worksheet objects that you can store the specific sheets your working in. So I would do something like Dim currentSheet As Worksheet and then somewhere before this block of code you've posted (where appropriate) Set currentSheet = Sheets("A4"). You'll have to update any Range(...) and Cells(...) calls to be currentSheet.Range(...), but the advantage of this is that your Range and Cells calls will always reference Sheets("A4") -- they won't accidentally switch context if you make modifications to this macro later on. This is how you also avoid relying on ActiveSheet, in general.

    0 讨论(0)
提交回复
热议问题