许多子程序的变量:代码清理
Variables for many subroutines: code clean up
我已经思考并搜索了好几个小时的解决方案,但无法找到我的基本问题的答案(显然对我来说很难):
所以我有很多子程序:
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
那么,我怎样才能避免在所有子程序中声明所有这些变量和工作簿。
我一直在尝试我在几乎每个网站上读到的内容:
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
您必须在子例程外创建一个public变量,这就是当您试图在子例程内声明它时会出错的原因。当您声明一个 public 变量时,它对所有子例程都是可见的 - 它将在您启动 运行 您的宏时创建。它在子例程之外声明的事实并不意味着声明不会发生。
请注意,您还可以使用 "Dim"(而不是 Public)在子例程外声明变量,但此类变量仅对同一模块内的子例程可见。 Public 变量将对所有模块中的所有例程可见。
要考虑的另一种方法是将您广泛需要的变量作为参数传递。例如在您的主例程中声明它们,然后将它们传递给需要它们的子例程。这通常比有很多 public 个变量更可取,但这两种方法都有其用途。
编辑:为响应 Jules 的评论而添加。
Jules 提出了一个非常好的观点——相信工作表代码块中的 "Public" 变量并不是真正的 public,而是仅对该工作表中的所有例程可见。但是,模块中的 public 声明实际上是 Public.
作为替代方案,您可以在模块中声明一个 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、私有变量、模块内部或外部变量等),并试图理解它们。感谢您的建议,但这些代码对我来说有点太高级了。
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
我已经思考并搜索了好几个小时的解决方案,但无法找到我的基本问题的答案(显然对我来说很难):
所以我有很多子程序:
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
那么,我怎样才能避免在所有子程序中声明所有这些变量和工作簿。 我一直在尝试我在几乎每个网站上读到的内容:
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
您必须在子例程外创建一个public变量,这就是当您试图在子例程内声明它时会出错的原因。当您声明一个 public 变量时,它对所有子例程都是可见的 - 它将在您启动 运行 您的宏时创建。它在子例程之外声明的事实并不意味着声明不会发生。
请注意,您还可以使用 "Dim"(而不是 Public)在子例程外声明变量,但此类变量仅对同一模块内的子例程可见。 Public 变量将对所有模块中的所有例程可见。
要考虑的另一种方法是将您广泛需要的变量作为参数传递。例如在您的主例程中声明它们,然后将它们传递给需要它们的子例程。这通常比有很多 public 个变量更可取,但这两种方法都有其用途。
编辑:为响应 Jules 的评论而添加。 Jules 提出了一个非常好的观点——相信工作表代码块中的 "Public" 变量并不是真正的 public,而是仅对该工作表中的所有例程可见。但是,模块中的 public 声明实际上是 Public.
作为替代方案,您可以在模块中声明一个 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、私有变量、模块内部或外部变量等),并试图理解它们。感谢您的建议,但这些代码对我来说有点太高级了。
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