2016-04-28 2 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 и книги во ВСЕХ субтитрах. Я пытался что я прочитал почти каждый сайт:

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

Являются ли ваши подпрограммы находящимися в том же рабочем листе или модулях? – Jules

+0

Nop, у меня есть модуль для каждой подпрограммы. –

+1

Если ваш код работает, я бы рекомендовал вам опубликовать его (а не только фрагменты!) На [codereview.se], где рецензенты VBA будут рассматривать каждую проблему с вашим кодом, от отступов, имен и комментариев до производительности и эффективности, и общая структура и дизайн. Нет ничего лучше, чем обращать внимание других людей на ваш код для изучения вещей. –

ответ

0

Мне нужно было запустить код, и, к счастью, я придумал решение. Вероятно, я сделал именно то, чего не следует делать, или это не рекомендуется, но снова у меня не было времени подумать о лучшем решении. Я просто изучаю разные типы переменных (Public, private, внутри или вне модуля и т. Д.) И пытаюсь понять их.Спасибо за ваше предложение, но те коды, которые немного слишком продвинуты для меня.

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

вы есть создать открытую переменную вне подпрограммы, поэтому вы получите ошибку WHe n вы пытаетесь объявить его в рамках подпрограммы. Когда вы объявляете общедоступную переменную, она видна для всех подпрограмм - и она будет создана в момент запуска вашего макроса. Тот факт, что он объявлен вне подпрограммы, не означает, что декларация не будет выполняться.

Обратите внимание, что вы также можете объявить переменную вне подпрограммы с помощью «Dim» (вместо «Public»), но такие переменные будут видны только подпрограммам в одном модуле. Публичные переменные будут видны для всех подпрограмм во всех модулях.

Другим подходом к рассмотрению является передача ваших широко используемых переменных в качестве параметров. например объявите их в своей основной процедуре, а затем передайте их подпрограммам, которые им нужны. Это часто предпочтительнее наличия множества общедоступных переменных, но оба подхода имеют свои преимущества.

Редактировать: Добавлено в ответ на комментарий Жюля. Жюль поднимает очень хорошую точку - полагает, что переменная «Public» в блоке кода рабочего листа не является общедоступной, но доступна только для всех подпрограмм на этом листе. Однако публичная декларация в модуле действительно общедоступна.

+1

Переменная 'Public' в модуле рабочего листа * является * общедоступной. Дело в том, что рабочий лист является * объектом *, поэтому общедоступная переменная на самом деле является общедоступным * экземпляром поля *, что означает, что к нему можно получить доступ только из экземпляра класса. Переменная '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 
Смежные вопросы