我已经思考并搜索了好几个小时的解决方案,但无法找到我的基本问题的答案(显然对我来说很难):
所以我有很多子程序:
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:EstudiosBibliotecaMercado Accionario ChilenoBBDD 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()
内部创建这些变量,它会抛出一个错误,并且在启动宏时不会读取Outside It。
我错过了一些基本的东西。
我特别感兴趣的是使变量。。。
Dim compañia As String
compañia = y.Sheets("Información Financiera").Range("A3")
对所有子例程使用full,因为我想对变量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
您必须在子例程外创建一个公共变量,这就是为什么当您试图在子例程内声明它时会出现错误。当您声明一个公共变量时,它对所有子例程都是可见的,并且它将在您开始运行宏时创建。它是在子例程外部声明的,这并不意味着声明不会发生。
请注意,您也可以使用"Dim"(而不是Public)在子例程外部声明变量,但此类变量仅对同一模块内的子例程可见。公共变量将对所有模块中的所有例程可见。
另一种需要考虑的方法是将广泛需要的变量作为参数传递。例如,在主例程中声明它们,然后将它们传递给需要它们的子例程。这通常比拥有许多公共变量更可取,但这两种方法都有其用途。
编辑:添加以回应Jules的评论。Jules提出了一个很好的观点——相信工作表代码块中的"Public"变量不是真正的公共变量,而是只有该工作表中的所有例程可见。但是,模块中的公共声明是真正的公共声明。
作为一种替代方案,您可以在模块中声明公共自定义类型,并且只使用一行进行本地声明。此解决方案比使用全局变量更安全。
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
我必须运行代码,幸运的是我想出了一个解决方案。也许我做了不该做的事,或者不建议做,但我没有时间思考更好的解决方案。我只是在学习不同类型的变量(公共、私有、模块内部或外部等),并试图理解它们。谢谢你的建议,但那些代码对我来说有点太先进了。
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