【问题标题】:Procedure too large VBA excel [closed]程序太大的VBA excel [关闭]
【发布时间】:2016-08-20 14:50:21
【问题描述】:

我需要一些帮助来缩短这段代码。

我需要将此代码 If (linha >= 20 And linha <= 21) 用于 50 行 (linha) 间隔

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  Dim foto As Range
  Dim destino As Range
  Dim linha As Long
  Dim fName As String
  Dim pName As String
  Dim iName As String
  Dim iNameClean As String
  Dim iNameExcel As String
  Dim fNameExcel As String

    Set foto = Target.Cells(1)
    Set destino = Me.Range("AU:BC,BN:BV,CG:CO,CZ:DH,DS:EA,EL:ET,FE:FM,FX:GF,GQ:GY,HJ:HR,IC:IK,IV:JD,JO:JW,KH:KP,NF:NN,NY:OG,OR:OZ,PK:PS")
    If Not Application.Intersect(foto, destino) Is Nothing Then
        linha = foto.Row


    If (linha >= 20 And linha <= 21) Then
        With ActiveSheet
    fName = Application.GetOpenFilename("Picture files (*.jpg;*.gif;*.bmp;*.tif), *.jpgs;*.gif;*.bmp;*.tif", , _
"Select picture to insert")
            iName = Dir("" & fName & "")
            If fName = "False" Then Exit Sub
            iNameClean = Left(iName, Len(iName) - 4)
            iNameExcel = "+Info"
            fNameExcel = "F:\path\EXCEL\" & foto.Offset(1, 3).Value & ".xlsx"
            With ActiveSheet
            .Unprotect Password:="1234"
                ActiveSheet.Pictures.Insert(fName).Select
                foto.Offset(0, 2).Formula = "=HYPERLINK(""" & fName & """,""" & iNameClean & """)"
                foto.Offset(0, 2).Font.ColorIndex = 1 ' preto
                foto.Offset(0, 2).Font.Size = 9
                foto.Offset(0, 2).Font.Underline = False
                foto.Offset(0, 3).Formula = "=HYPERLINK(""" & fNameExcel & """,""" & iNameExcel & """)"
                foto.Offset(0, 3).Font.ColorIndex = 1 ' preto
                foto.Offset(0, 3).Font.Size = 9
                foto.Offset(0, 3).Font.Underline = False
                With Selection.ShapeRange
                    .LockAspectRatio = msoFalse
                    .Height = ActiveCell.MergeArea.Height
                    .Width = ActiveCell.MergeArea.Width
                    .Top = ActiveCell.Top
                    .Left = ActiveCell.Left
                End With
             .Protect Password:="1234"
            End With
        End With
    End If

End Sub

【问题讨论】:

  • 如果你可以edit标题简洁地解释代码的作用,并在问题正文中扩展一些周围的上下文,这将是一个完美的问题为Code Review。就目前而言,对于 Stack Overflow 来说,这个问题有点太宽泛了。
  • 为什么需要缩短代码?如果您收到错误“程序太大”,那么只需将其分解为几个程序即可。如果超出模块大小,则将您的代码分布在多个模块中。
  • @Ralph 如果你得到“程序太大”的错误,你有更大的问题,需要阅读一下SRP ;-)
  • @Ralph 它很可能适用于此。假设If 块的内容可以划分为另一个接受一些参数的子/函数。
  • 哦等等,是不是If linha &gt;= x And linha &lt;= y Then块复制+粘贴了这么多次程序长度居然超出了限制?如果是这样,那么是的@Ralph 的链接有你的答案,你的问题有点不清楚。也就是说,如果您正在寻求帮助,将其分解成更易于管理的部分并使其更高效,Code Review 仍然是您的理想去处。

标签: excel vba


【解决方案1】:

首先,不要将整个函数过程放在事件处理程序中。仅放置将事件路由到适当过程所需的最少代码。这使您的事件处理程序简洁,并且更易于维护。大部分工作将在其他程序中进行。

我将定义一个新过程DoStuff 来处理linhas,我们发送给DoStuff 的参数可以在Case 开关内控制。

这样,DoStuff 过程体不需要复制 50 次或更多,您可以简单地添加到 Worksheet_Change 事件处理程序中的 Case 语句,并进行更改(如果需要)可选参数。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  Dim foto as Range
  Dim destino as Range
  Dim linha As Long

    Set foto = Target.Cells(1)
    Set destino = Me.Range("AU:BC,BN:BV,CG:CO,CZ:DH,DS:EA,EL:ET,FE:FM,FX:GF,GQ:GY,HJ:HR,IC:IK,IV:JD,JO:JW,KH:KP,NF:NN,NY:OG,OR:OZ,PK:PS")
    If Not Application.Intersect(foto, destino) Is Nothing Then
        linha = foto.Row
    End If

    Select Case linha
        Case 20, 21
            Call DoStuff(foto, 1, 9, "1234")

        '### Simply add additional "Case" statements for each linha pair
        '    NOTE: You can send different parameters to the DoStuff procedure!
        Case 22, 23
            Call DoStuff(foto, 1, 9, "ABCD", "G:\another path\Excel\", ".xlsb")


        'Etc...

    End Select

End Sub

这是DoStuff 过程。此过程采用foto 范围(或技术上的任何范围对象)和passwordfilepathfileExt(在With 块中使用)的可选参数(具有默认值)。

Sub DoStuff(foto as Range, _
            Optional fontColor as Long=1, 
            Optional fontSize as Long=9, _
            Optional password as String="1234", _
            Optional filePath as String="F:\path\EXCEL\", _
            Optional fileExt as String=".xlsx")

  Dim fname as String
  Dim pName As String
  Dim iName As String
  Dim iNameClean As String
  Dim iNameExcel As String
  Dim fNameExcel As String

    If Right(filePath,1) <> "\" Then filePath = filePath & "\"

    fName = Application.GetOpenFilename("Picture files (*.jpg;*.gif;*.bmp;*.tif), *.jpgs;*.gif;*.bmp;*.tif", , _
    "Select picture to insert")
    iName = Dir("" & fName & "")
    If fName = "False" Then Exit Sub
    iNameClean = Left(iName, Len(iName) - 4)
    iNameExcel = "+Info"
    fNameExcel = filePath & foto.Offset(1, 3).Value & fileExt

    With foto.Parent 'Worksheet
        .Unprotect Password:=password
        .Pictures.Insert(fName).Select
        With foto.Offset(0,2)
            .Formula = "=HYPERLINK(""" & fName & """,""" & iNameClean & """)"
            .Font.ColorIndex = fontColor ' preto
            .Font.Size = fontSize
            .Font.Underline = False
        End With
        With foto.Offset(0, 3)
            .Formula = "=HYPERLINK(""" & fNameExcel & """,""" & iNameExcel & """)"
            .Font.ColorIndex = fontColor ' preto
            .Font.Size = fontSize
            .Font.Underline = False
        End With
        With Selection.ShapeRange
            .LockAspectRatio = msoFalse
            .Height = foto.MergeArea.Height
            .Width = foto.MergeArea.Width
            .Top = foto.Top
            .Left = foto.Left
        End With
     .Protect Password:=password
    End With

End Sub

【讨论】:

  • 好建议。在单个事件处理程序中看到 200 行代码是我的烦恼。一个事件应该总是调用一个动词(方法),只有在程序运行时可能会改变的参数。
  • 大卫·泽门斯 你就是男人!非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 2021-06-11
  • 2012-07-12
  • 2011-04-07
  • 1970-01-01
相关资源
最近更新 更多