2016-04-28 14 views
0

我一直在思考和尋找解決方案的好幾個小時,但不能拿出我的基本問題的答案(顯然很難對我):許多子程序的變量:代碼清理

所以我有很多的子程序:

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 

所以,我怎麼能避免申報所有這些variabl的es和所有潛艇上的工作簿。 我一直在嘗試什麼我讀了幾乎每一個網站:

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(正在重置它作爲一個數組做循環字符串),並把forOUTPUT子程序爲:

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 
+0

您的子程序是否位於同一個工作表或模塊中? – Jules

+0

Nop,我有一個模塊用於每個子程序。 –

+1

如果您的代碼正常工作,我會熱烈推薦您在[codereview.se]上發佈它(不僅僅是代碼段!),其中VBA評審人員將使用代碼解決每一個問題,從縮進,命名和註釋到性能和效率,和整體結構和設計。沒有什麼比得到其他人對你的代碼的反饋來學習東西。 –

回答

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 
1

創建一個子程序之外的公共變量,這就是爲什麼你會得到錯誤磨片你試圖在子程序中聲明它。當你聲明一個公共變量時,它對所有的子程序都是可見的 - 它將在你開始運行你的宏時創建。它在子程序之外聲明並不意味着聲明不會發生。

請注意,您也可以使用「Dim」(而不是Public)在子例程之外聲明變量,但這些變量僅對同一模塊內的子例程可見。公共變量將在所有模塊中的所有例程中可見。

另一種考慮的方法是將您廣泛需要的變量作爲參數傳遞。例如在主例程中聲明它們,然後將它們傳遞給需要它們的子例程。這通常比擁有大量公共變量更可取,但兩種方法都有其用處。

編輯:添加爲了迴應Jules的評論。 Jules提出了一個非常好的觀點 - 相信工作表代碼塊中的「Public」變量並非真正公開的,而只能在該工作表中的所有例程中看到。但是,模塊中的公開聲明是真正公開的。

+1

工作表模塊中的公共變量*爲* public。只是工作表碰巧是* object *,所以公共變量實際上是一個public * instance字段*,這意味着它只能從類的一個實例中訪問。標準代碼模塊中的「Public」變量被稱爲「全局變量」,通常被認爲是不好的做法。 –

+0

@馬特杯。哈!感謝您的明確解釋。這非常合理。我總是假設使用「Global」在代碼模塊中聲明一個變量只是宣佈「Public」的一種老式方式。但它似乎比這更微妙一些。 – HedgePig

+0

'Global'關鍵字確實被'Public'取代,並且被認爲已過時,方法調用的'Call'關鍵字和值賦值的'Let'關鍵字也被視爲已過時。所以你的假設是正確的 - 我的意思是「全局」在整個項目中「可見」,而不是「全局」(廢棄的關鍵字);-) –

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