Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: 1
RSS
Передача значений переменных из одного макроса в другой. Вызов макроса из макроса
 
Доброго времени суток, Планетяне!
От проверки системных ограничений Excel'я решил вернуться к более рабочим вопросам. Прошу совета по проблеме. Итак:
1. Есть у меня базовый исполнительный макрос. Вообще он хранится в личной подключаемой надстройке, но в примере он помещён в книгу, вместе с предварительным макросом
2. Есть предварительный макрос. С его помощью я получаю 2 переменные (диапазон и разделитель) для последующей передачи их в исполнительный макрос
3. вопрос: как это грамотно сделать? Напрямую вызывать исполнительный макрос из предварительного не получается. Ни call, ни run…
4. Изменится ли (и как) порядок передачи переменных, если предварительный макрос находится в модуле книги, а исполнительный в личной надстройке и между ними настроена ссылочная связь, как мне подсказал уважаемый Казанский в этой теме?

Зачем мне это?
Опять же - для удобства. Исполнительный макрос не меняется, выполняя одну и ту же работу. Меняются только переменные в нём: например в этом - это разделитель и диапазон. Иногда мне удобно их задать руками (для Selection, как в примере), а иногда онм задаются в составе другого большого макроса, одним из этапов которого будет являться этот.

Проверяю на макросе, взятом из этой моей темы.
Вот эти 2 макроса в 1 модуле
Изменено: Jack Famous - 30 Окт 2017 11:57:20
«Тот, кто несет фонарь, спотыкается чаще, чем тот, кто идет следом.»
Иоганн Пауль Фридрих Рихтер
 
Не сочтите за ап)))
Внутри одного модуля разобрался, "засунув" меняющиеся переменные (переменные переменные  :D ) между Option Explicit и Sub'ом первого модуля — то есть, объявив их переменными уровня модуля. Совет взял отсюда
Теперь, как я понимаю, нужно экспериментировать со случаем из личной надстройки. Буду рад советам и продолжаю копать)
Код
Option Explicit
Dim rngTOR As Range
Dim DelimTOR$

Sub TextOnRowsInRange_BASE2()
Dim cl As Range, rngTmp As Range
Dim strTmp$
Dim Arr() As String
Dim i&, n&, j&, k&, a&, max&

    If DelimTOR = "" Then Exit Sub
    
    If rngTOR.Columns.Count > 20 Or rngTOR.Rows.Count > 10000 Or rngTOR.Cells.Count > 100000 Then
        MsgBox "Слишком много выделено!", vbExclamation, "Ошибка выделения"
        Exit Sub
    End If

Application.ScreenUpdating = 0
    For i = rngTOR.Rows.Count To 1 Step -1
'===
        max = 0
        For j = 1 To rngTOR.Columns.Count
                strTmp = rngTOR(i, j).Value & DelimTOR
                   Arr = Split(strTmp, DelimTOR)
                   a = UBound(Arr)
            max = IIf(max > a, max, a)
        Next
        If max <= 1 Then GoTo nx
'===
        rngTOR(i, 1).Offset(1, 0).Resize(max - 1).EntireRow.Insert Shift:=xlDown ', CopyOrigin:=xlFormatFromLeftOrAbove
   For j = 1 To rngTOR.Columns.Count
            With rngTOR(i, j)
            If InStr(rngTOR(i, j), DelimTOR) Then
                strTmp = .Value '& DelimTOR
                Arr = Split(strTmp, DelimTOR)
                a = UBound(Arr)
                    Set rngTmp = .Resize(a)
                    For k = 0 To a
                        rngTmp(k + 1, 1).Value = Arr(k)
                    Next k
            End If
            End With
        Next j
'===
nx:
    Next i
Application.ScreenUpdating = 1
End Sub
'=======================================================================================================================
Sub TextOnRowsInRange_Choose2()

DelimTOR = InputBox("Введите символ-разделитель")
    If DelimTOR = "10" Then DelimTOR = Chr(10) 'ввести "10" для использования в качестве разделителя "перенос строки"
Set rngTOR = Selection
Application.Run "TextOnRowsInRange_BASE2"
End Sub
Изменено: Jack Famous - 30 Окт 2017 13:06:28
«Тот, кто несет фонарь, спотыкается чаще, чем тот, кто идет следом.»
Иоганн Пауль Фридрих Рихтер
 
Кароч  :D (инфу, как и ранее, взял у Дмитрия Щербакова на сайте)
Вроде работает так: переменные нужно объявить в области объявлений (перед Sub) как Public, а не Dim в исполнительном макросе, что лежит в личной надстройке. Затем связать книгу и надстройку (ссылка в шапке) и вуаля))) не знаю, насколько стабильно, но с этим примером получилось. Подскажите, если тупанул где или подводные камни какие имеются, на что нужно обратить внимание и что учесть…

Вот ещё ссылка на официальные данные по этому вопросу от мелкомягких  :)
Изменено: Jack Famous - 30 Окт 2017 13:19:55
«Тот, кто несет фонарь, спотыкается чаще, чем тот, кто идет следом.»
Иоганн Пауль Фридрих Рихтер
 
Доброго времени суток, Планетяне!
Увидел, что из макроса в макрос переменные можно передавать в скобках, как в функции: Application.Run "Макрос(a,b,c,rng)".
Подскажите пожалуйста как правильно это сделать и какие нюансы? Можно ли Optional, например, использовать и так далее…

Базовый макрос находится в личной надстройке. Вызываю его из модулей книг.
Изменено: Jack Famous - 15 Мар 2018 18:36:19
«Тот, кто несет фонарь, спотыкается чаще, чем тот, кто идет следом.»
Иоганн Пауль Фридрих Рихтер
 
В общем, то вопрос в чём? Как передать переменную из одного макроса в другой?
Решений несколько:
-Можно через глобальную переменную
Public DelimTOR as String
-Можно просто передать как вы выше указывали
Call TextOnRowsInRange_BASE2(DelimTOR)

Sub TextOnRowsInRange_BASE2(DelimTOR)
------------------
End Sub
-Ну или так с указанием точного модуля
Макросы.TextOnRowsInRange_BASE2 (DelimTOR)
Я обычно использую точное указание модуля, на случай если имена макросов могут повторяться.
-Если Вы хотите запустить макрос вне надстройки, то-бишь перенести переменную в макрос, который находится в Вашей надстройке, то можно так:
Application.Run "Надстройка.xlam!Макросы.TextOnRowsInRange_BASE2", DelimTOR

Sub TextOnRowsInRange_BASE2(DelimTOR)
------------------
End Sub
Имена передаваемых аргументов могут быть другими, передаётся только их порядок, последовательность.
Изменено: Alemox - 15 Мар 2018 19:27:47
Никаких врагов, зато и никаких друзей.
 

Jack Famous,  очивидно, но, как говорил мой препод по математике, уметь доказывать:
Макрос, или подпрограмм (Sub от Subroutine) отличается от функции только тем, что поcледняя возвращает значение плюс к тем что ей передали. Все остальные правила передачи аргументов остаются/

Надеюсь никого сильно не удивить, но угадайте, что выдадут три принта?

Код
Sub tt2()
B = 1
Call tt(B)
Debug.Print B
Debug.Print ttt(B)
Debug.Print BEnd SubSub tt(a)
a = a + 1
End Sub
sub tt(a)
a=a+1
end sub
Function ttt(a)
a = a + 1
ttt = a
End Function 
То есть надо помнить, а иногда и пользоваться тем, что изменяя передавая параметр (аргумент) и изменив его,  мы получаем измененное значение переменой и в родительском процессе.

Изменено: БМВ - 15 Мар 2018 21:00:38
 
Alemox, простите - не увидел вашего сообщения… Подробно, однако  :D
Application.Run "Надстройка.xlam!Макросы.TextOnRowsInRange_BASE2", DelimTOR — вот этот способ был нужен!
Спасибо вам большое!

БМВ, спасибо вам большое! В коде что-то перепутано, но основное уяснил - буду пробовать!
Изменено: Jack Famous - 15 Мар 2018 20:57:00
«Тот, кто несет фонарь, спотыкается чаще, чем тот, кто идет следом.»
Иоганн Пауль Фридрих Рихтер
 
Цитата
Jack Famous написал:
В коде что-то перепутано
да, удалил подпрограмку одну случайно. Исправил.
 
Цитата
БМВ написал: изменяя передавая параметр (аргумент) и изменив его,  мы получаем измененное значение переменой и в родительском процессе.
...или получаем ошибку вычислений :)
Не стоит забывать о ByRef и ByVal
 
vikttur, согласен и понятно уж  лучше ошибка, чем непонятно почему измененное значение,
Страницы: 1
Читают тему (гостей: 1)
Наверх