Excel VBA - Вызов / Ссылка на именованный диапазон из другого Sub - PullRequest
0 голосов
/ 20 ноября 2018

Это мой первый пост в StackOverflow, поэтому, если я что-то упустил, пожалуйста, дайте мне знать!

КОНТЕКСТ: Я впервые собирал код VBA и до сих пор сумел написатькод из тонны различных потоков и примеров кода со всего Интернета.Поскольку я новичок, я еще не до конца понимаю, как работают коды VBA - это в основном метод проб и ошибок и много копий, пока я не пойму это правильно.В результате я представляю, что код намного длиннее, чем может быть, и не так эффективен.Однако, поскольку я новичок, расширенные коды редко имеют смысл для меня, поэтому я придерживаюсь более базовых решений, так как сначала мне нужно понять код и иметь возможность интегрировать его различными способами, в зависимости от ситуации, и сделать еголегко читаемый для других, если это необходимо.Причина, по которой я говорю все это, состоит в том, что вы можете понять мой уровень опыта и что ожидать от моих возможностей понимания VBA, поэтому заранее благодарю вас за ваше терпение!Я покажу вам часть моего кода ниже.

ВОПРОС: У меня есть несколько диапазонов, определенных в моих сабвуферах, таких как:

Define range names:
X.Sheets("Sheet1").Range("B4").Name = "Type1"
X.Sheets("Sheet1").Range("B9").Name = "SubTotal1"
X.Sheets("Sheet1").Range("A6:F8").Name = "Data1"

X.Sheets("Sheet1").Range("B11").Name = "Type2"
X.Sheets("Sheet1").Range("B16").Name = "SubTotal2"
X.Sheets("Sheet1").Range("A13:F15").Name = "Data2"

X.Sheets("Sheet1").Range("B18").Name = "Type3"
X.Sheets("Sheet1").Range("B23").Name = "SubTotal3"
X.Sheets("Sheet1").Range("A20:F22").Name = "Data3"

Y.Sheets("Sheet1").Range("A4:A6").Name = "Period"
Y.Sheets("Sheet1").Range("B4:B6").Name = "Name"
Y.Sheets("Sheet1").Range("D4:D6").Name = "Code"
Y.Sheets("Sheet1").Range("E4:E6").Name = "Type"
Y.Sheets("Sheet1").Range("F4:K4").Name = "Data"

Этот диапазон имен используется в каждом сабвуфере (у меня около 15, еще около 165 необходимо..) для копирования и вставки информации из Рабочей книги X в Рабочую книгу Y. Поскольку повторное использование кода для каждого подпрограммы является излишним, я хотел бы иметь возможность поместить эти диапазоны в отдельный подпункт и вызывать его в каждом новом подпункте длясэкономьте время и пространство.

Если возможно, я также хотел бы сделать то же самое со следующим кодом, который относится к диапазонам, определенным выше:

'Insert Type1 Data from X:

If X.Sheets("Sheet").Range("SubTotal1").Value > 0 Then
Range("Type1").Copy
Y.Sheets("Sheet1").Range("Type").Insert xlShiftDown
Range("Data1").Copy
Y.Sheets("Sheet1").Range("Data").Insert xlShiftDown

'Insert Period:
X.Sheets("Sheet1").Range("C3").Copy
Y.Sheets("Sheet1").Range("Period").Insert xlShiftDown

'Insert Name:
X.Sheets("Sheet1").Range("C12").Copy
Y.Sheets("Sheet1").Range("Name").Insert xlShiftDown

'Insert Code Type:
X.Sheets("Sheet1").Range("C10").Copy
Y.Sheets("Sheet1").Range("Code").Insert xlShiftDown
End If

Этот код и еще 6подобные ему (Тип 1-6) также избыточны в других подпрограммах, поэтому в идеале я бы поместил их в отдельную подпрограмму и при необходимости вызывал их, поскольку это сделает мой код бесконечно короче.Я использую это в начале своих подпрограмм для определения листов X и Y:

Dim X As Workbook
Dim Y As Workbook

'Define workbooks:
Set X = Workbooks.Open("C:\Users\user\Folder\File.xlsx")
Set Y = ThisWorkbook

Если я что-то упустил, чтобы помочь вам получить полную картину, пожалуйста, дайте мне знать.Я знаю, что это долго, поэтому спасибо, если вы не торопитесь, чтобы ответить.Я очень ценю это!

РЕДАКТИРОВАТЬ: Чтобы дать лучший пример того, что я имею в виду, я представляю Subs происходит что-то вроде этого:

Sub Sub1

Call Sub "RangeNames"
Call Sub "Insert Type1 Data while referring to RangeNames"
Call Sub "Insert Type2 Data while referring to RangeNames"

End Sub

И / или

Sub Sub2

Call Sub "RangeNames"
Call Sub "If RangeName 'SubTotal 3' > 0 then Insert Type3 Data while referring to RangeNames"

End Sub

РЕДАКТИРОВАТЬ 2:

Для @SJR:

Sub Sub1
Dim X As Workbook
Dim Y As Workbook

Set X = Workbooks.Open("C:\Users\user\Folder\File.xlsx")
Set Y = ThisWorkbook

X.Sheets("Sheet1").Range("B4").Name = "Type1"
X.Sheets("Sheet1").Range("B9").Name = "SubTotal1"

Y.Sheets("Sheet1").Range("E4:E6").Name = "Type"

Sub2

End Sub

Sub 2:

Sub Sub2

If X.Sheets("Sheet").Range("SubTotal1").Value > 0 Then <- ERROR HAPPENS HERE
Range("Type1").Copy
Y.Sheets("Sheet1").Range("Type").Insert xlShiftDown

End If

End Sub

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Если вы собираетесь добавить еще 165 сабвуферов, могу ли я предложить взглянуть на loops и / или массивы ?

Для его разработки может потребоваться примерно одно и то же время (с учетом кривой обучения), но код будет примерно в 150 раз короче (делать все в 1-2-3 подпункта) и намного проще в обслуживании. Это, а также в сочетании с предлагаемыми параметрами для вызова аналогичной функциональности из других подпрограмм или функций, будет намного эффективнее.

Вот первые результаты от Google, когда речь идет о циклах и массивах, и после быстрого просмотра они действительно покрывают основные потребности:

Заключительный совет, имейте в виду, что чем меньше вы взаимодействуете с книгами из VBA, тем быстрее будут работать ваши макросы. То есть: загрузить весь диапазон в массив, выполнить необходимое преобразование, а затем поместить его обратно в рабочую книгу - вы обращаетесь к рабочей книге только 2 раза по мере необходимости. С другой стороны, если вы используете vba для копирования ячейки A в ячейку B, несколько десятков / сотен тысяч раз ... это будет медленнее.

0 голосов
/ 20 ноября 2018

То, что вам нужно, это аргументы (или параметры).

например.

Sub CopyAndInsertStuff(sourceLocation as String, destinationLocation as String)

    Set wbSrc = Workbooks(sourceLocation)
    Set wbDst = Workbooks(destinationLocation)

    'Do your copying and inserting logic here...

End Sub

Затем вызовите эту функцию:

Call CopyAndInsertStuff("C:\path\to\source\File.xlsx", "C:\path\to\destination\File.xlsx")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...