许多子程序的变量:代码清理

时间:2016-04-28 02:00:58

标签: excel vba global-variables subroutine

我一直在思考和寻找解决方案的几个小时,但无法得出我的基本问题的答案(对我来说显然很难):

所以我有很多子程序:

Sub OUTPUT()

Call CompañiasCubiertas
Call RangosDatos
Call EERR
Call Balance
Call Flujo
Call Indicadores
Call FormatoEERR
Call FormatoBalance
Call FormatoFlujo
Call FormatoIndicadores

End Sub

在每个潜艇中,我有许多变量和工作簿声明重复:

Dim y As Workbook
Dim x As Workbook

Dim rangoi As Integer
Dim rangof As Integer
Dim compañia As String
Dim oipf As Integer
Dim ogpf As Integer 
Dim ogp As Integer 
Dim Fechai As Long
Dim Fechaf As Long
Dim Fechaper1 As Long
Dim Fechaper2 As Long


Set y = Application.ActiveWorkbook
Set x = Application.Workbooks.Open("G:\Estudios\Biblioteca\Mercado Accionario Chileno\BBDD Oficial.xlsm")

compañia = y.Sheets("Información Financiera").Range("A3")

'Definir rangos para buscar los datos

Fechai = y.Sheets("Información Financiera").Range("C4").Value
Fechaf = y.Sheets("Información Financiera").Range("D4").Value
Fechaper1 = y.Sheets("Información Financiera").Range("C8").Value
Fechaper2 = y.Sheets("Información Financiera").Range("D8").Value
rangoi = Application.Match(Fechai, y.Sheets("Información Financiera").Range("E2:E300"), 0) + 1
rangof = Application.Match(Fechaf, y.Sheets("Información Financiera").Range("E2:E300"), 0) + 1

那么,我怎样才能避免在ALL子系统中声明所有这些变量和工作簿。 我一直在尝试几乎在每个网站上阅读的内容:

Public rangoi As Integer
Public rangof As Integer

依旧....但是如果我在OUTPUT()中创建这些变量,它会抛出一个错误,当我启动宏时,它将不会被读取。

我遗漏了一些基本的东西。

我对制作变量特别感兴趣......

Dim compañia As String
 compañia = y.Sheets("Información Financiera").Range("A3")

...对所有子例程都很有用,因为我想在变量compañia上做一个循环(将其重置为一个字符串数组)并在for中加OUTPUT子程序为:

 Sub OUTPUT()
    For i=1 To UBound(compañia)

Call subs1 ' subs1(compañia) , meaning the value of compañia changes the value of subroutines
Call subs2 ' subs2(compañia)
Call subs3 ' subs3(compañia)

Next i
End Sub

3 个答案:

答案 0 :(得分:1)

在子程序之外创建一个公共变量,这就是当你试图在子程序中声明它时出错的原因。声明公共变量时,它对所有子例程都可见 - 它将在您开始运行宏时创建。它在子例程之外声明的事实并不意味着声明不会发生。

请注意,您还可以使用“Dim”(而不是Public)在子例程外声明变量,但这些变量仅对同一模块中的子例程可见。公共变量对所有模块中的所有例程都是可见的。

另一种需要考虑的方法是将广泛需要的变量作为参数传递。例如在主例程中声明它们,然后将它们传递给需要它们的子例程。这通常比拥有大量公共变量更可取,但这两种方法都有其用途。

编辑:添加以回应Jules的评论。 Jules提出了一个非常好的观点 - 相信工作表代码块中的“公共”变量不是真正公开的,而是仅对该工作表中的所有例程可见。但是,模块中的公开声明确实是公开的。

答案 1 :(得分:0)

作为替代方法,您可以在模块中声明公共自定义类型,并且只使用一行来在本地声明。此解决方案比使用全局变量更安全。

Module1.bas

Public Type CustomType
    y As Workbook
    x As Workbook
    compania as String '<-- I don't have accent on my machine.
    rangoi As Integer
    rangof As Integer
    oipf As Integer
    ogpf As Integer
    ogp As Integer
    Fechai As Long
    Fechaf As Long
    Fechaper1 As Long
    Fechaper2 As Long
End Type

Module2.bas

Public Sub Sub1()
   dim lCustom as CustomType

   set lCustom.x = ActiveWorkBook '<-- just a sample
   lCustom.loipf = 1
End Sub

Module3.bas

Public Sub Sub2()
   dim lCustom as CustomType

   set lCustom.x = ActiveWorkBook '<-- just a sample
   lCustom.loipf = 1
End Sub

答案 2 :(得分:0)

我必须运行代码,幸运的是我想出了一个解决方案。可能我完全做了它应该做的事情,或者不推荐,但我再也没有时间考虑更好的解决方案。我只是学习了不同类型的变量(公共,私有,模块内外等等),并试图理解它们。谢谢你的建议,但那些代码对我来说有点太高级了。

Public compañia2() As String
Public compañia As String 

Sub OUTPUT()
Application.ScreenUpdating = False 'To avoid screen flickering
Application.DisplayAlerts = False 'Mensajes de alertas desactivado

CompañiasCubiertas
RangosDatos

For i = 1 To UBound(compañia2)
compañia = compañia2(i)
EERR
Balance
Flujo
Indicadores
FormatoEERR
FormatoBalance
FormatoFlujo
FormatoIndicadores

Next i

Application.DisplayAlerts = True
Application.ScreenUpdating = True 'To avoid screen flickering
End Sub

Sub CompañiasCubiertas()

'Other code for declaration of variables and other stuff

ReDim compañia2(x.Sheets.Count - 3 + 1) ' Define lenght of the array

For i = 1 To x.Sheets.Count - 2
compañia2(i) = y.Sheets("CompañiasCubiertas").Range("A" & i + 2).Value ' Fill array
Next i

End Sub