Выбрать дату в календареВыбрать дату в календаре

Страницы: 1 2 3 След.
Win XP - тест возможности создания временного файла в папке Пользователя средствами VBA
 
Ну раз Environ так поддерживают - буду рад работать с ним))
Спасибо! И за остальную информацию!

Цитата
Игорь написал:
вот, например http://scriptcoding.ru/2013/06/27/wscript-shell-specialfolders/
Не, я имел в виду полные пути самих дирректорий
- Win XP под руками нет, и мне была интересна именно структура папок.

Впрочем, я не учёл "редиректед"
- как подсказал тов. БМВ, так что наверное уже не важно)

Буду работать с Environ("TEMP") :)
Win XP - тест возможности создания временного файла в папке Пользователя средствами VBA
 
Oleg Boyaroff, я мало знаком с Environ; прочитал, будто она не всегда работает.
Искать UserFolder через "Ubound - 1" конечно тоже не универсальный метод))
Но если на всех версиях винды начиная с XP он сработает
- меня это устраивает!
Win XP - тест возможности создания временного файла в папке Пользователя средствами VBA
 
!! Уточняю название темы:
Win XP - тест возможности создания временного файла в папке Пользователя ср-вами VBA

Описание темы: Также интересует структура папок SpecialFolders в Win XP
Win XP - тест возможности создания временного файла в папке Пользователя средствами VBA
 
Здравствуйте)

Я подыскиваю папку (каталог) для хранения временных .txt файлов (эти файлы будут создаваться и удаляться только на время выполнения процедуры).
Остановил выбор на папке Пользователя.
Почему?

Основная причина в том, что папка Пользователя разрешает создание файлов (!!!)
- по крайней мере в Win 8.1 (да, я люблю Win 8.1).

Этот факт (!!!) теперь мне нужно проверить в Win XP
- хотя бы ещё и потому что там совсем другая структура каталогов (я подглядывал здесь: https://habr.com/ru/post/70922/).
Код
Option Explicit
Private Sub Workbook_Open()

Const zQcQ1q As Double = 100000000000000#
Const zQcQ2q As Double = 999999999999999#

Dim zQ0q As String
Dim zQ1q As String
Dim zQFq As Variant
Dim zQsq As Variant
Set zQsq = CreateObject("WScript.Shell").SpecialFolders: zQ0q = _
    zQsq("MyDocuments")

Dim zQiq As Variant
Dim zQSplitq() As String
    zQSplitq = _
      Split(zQ0q, "\")
            zQ0q = "" '!!!

    For zQiq = 0 To UBound( _
    zQSplitq) - 1: zQ0q = zQ0q & _
    zQSplitq(zQiq) & "\"
    Next

    zQ1q = _
    zQ0q & Application.WorksheetFunction.RandBetween(zQcQ1q, zQcQ2q) & ".txt"
Set zQFq = CreateObject("Scripting.FileSystemObject").CreateTextFile( _
    zQ1q)

    For Each _
    zQsq In zQsq
    zQFq.WriteLine _
    zQsq
    Next: zQFq.Close '!!!

Shell "explorer.exe" & " " & zQ0q, vbNormalFocus
Shell "notepad.exe " & " " & zQ1q, vbNormalFocus
                        Kill zQ1q '!!!
Beep
End Sub

Что код делает:
  1. Находит SpecialFolders("MyDocuments") - которая примечательна тем, что во всех версиях винды она лежит прямо в папке Пользователя.
  2. Находит папку Пользователя - через Split по "\" и через "UBound - 1".
  3. Создаёт в папке Пользователя .txt файл со случайным именем.
  4. Записывает в этот .txt все возможные SpecialFolders.
  5. Открывает этот .txt и папку Пользователя через Shell.
  6. Удаляет этот .txt.
  7. Передаёт на секретную веб-страницу данные фашего паспорта и дебетовой карты (на самом деле нет)))
В общем, я вполне уверен, что папка Пользователя в Win XP тоже разрешает создание файлов. Но я буду признателен, если кто-то из владельцев хрюши здесь это подтвердит))
И ещё мне не помешает список "всех возможных SpecialFolders" (см. п. 4).

Заранее спасибо!
VBA: поместить элементы массива в аргументы Application.Run
 
Код
Public zQQCancel As Boolean

'--------------------------------------------------
Option Explicit

'--------------------------------------------------
Sub zQCallingSub()

Call zQSubQ0(Array( _
Array("zQSubQ1", 1, Application, "String", Array(1, 2, 3, 4)), _
Array("zQSubQ2", 1, Application, "String", Array(1, 2, 3, 4)), _
Array("zQSubQ3", 1, Application, "String", Array(1, 2, 3, 4)), _
Array("zQSubQ4", 1, Application, "String", Array(1, 2, 3, 4)) _
))
End Sub

'--------------------------------------------------
Sub zQSubQ0(zQArgs As Variant)

Dim zQEach As Variant

For Each zQEach In zQArgs
If zQQCancel = True Then zQQCancel = False: Exit Sub

Select Case UBound(zQEach)
Case 0: Application.Run zQEach(0)
Case 1: Application.Run zQEach(0), zQEach(1)
Case 2: Application.Run zQEach(0), zQEach(1), zQEach(2)
Case 3: Application.Run zQEach(0), zQEach(1), zQEach(2), zQEach(3)
Case 4: Application.Run zQEach(0), zQEach(1), zQEach(2), zQEach(3), zQEach(4)
Case 5: Application.Run zQEach(0), zQEach(1), zQEach(2), zQEach(3), zQEach(4), zQEach(5)
Case 6: Application.Run zQEach(0), zQEach(1), zQEach(2), zQEach(3), zQEach(4), zQEach(5), zQEach(6)
Case 7: Application.Run zQEach(0), zQEach(1), zQEach(2), zQEach(3), zQEach(4), zQEach(5), zQEach(6), zQEach(7)
Case 8: Application.Run zQEach(0), zQEach(1), zQEach(2), zQEach(3), zQEach(4), zQEach(5), zQEach(6), zQEach(7), zQEach(8)
Case 9: Application.Run zQEach(0), zQEach(1), zQEach(2), zQEach(3), zQEach(4), zQEach(5), zQEach(6), zQEach(7), zQEach(8), zQEach(9)
Case Else: MsgBox "!!!", vbCritical: Exit Sub
End Select
Next

Beep
End Sub

'--------------------------------------------------
'Runеные сабы оставил за кадром.
Собственно, вопрос:
можно ли вот этот Select Case как-то, ну чтобы Run глотал zQEach целиком; но НЕ как массив (как например Run глотает его 5й элемент, zQEach(5); который сам по себе массив Array(1, 2, 3, 4)), а нужна какая-то херня, которая бы каждый элемент zQEach - пихнула бы автоматически в поле аргумента Run.
??? есть или нет такая буква

Edit: на другом форуме мне подсказали, что VBA так не умеет.
Изменено: RazorBaze - 03.05.2020 15:23:33
общие макросы для Excel и Word
 
Добрый день!

Я написал макрос сохранения копии файла, который работает и в Excel, и в Word.
Проблема в том, что сейчас он хранится в двух разных файлах-шаблонах:
• Normal.dotm для Word;
• PERSONAL.XLSB для Excel.

Соответственно, если я улучшаю один
- мне приходится дублировать изменения в другом.

ВОПРОС:
есть ли способ подключения какой-то общей библиотеки, или я не знаю чего, чтобы макросы загружались оттуда?
Чтобы это был один общий файл, к которому обращались бы и Word, и Excel.

__________________________________________
РЕШЕНИЕ (2020 - никак руки не доходили написать):

Оказалось, всё проще))
Берёшь код, и пишешь его где-то в одном месте (проекте)
- либо в Word, либо в Excel; и уже из него
- вызываешь какие тебе надо документы (из Экселя - Вордовские, почему бы и нет),
как угодно их форматируешь и т.д.; события всякие тоже там будут работать
(т.е. события Ворда - пишешь тоже в Экселе; в общем, всё в одном проекте).

))) Можно, конечно, и фигню 2019го года допилить
- мелкомягким назло XD но пока оказалось не обязательно)

__________________________________________
РЕШЕНИЕ (2019):

Код
Sub zSubQ1()

Dim QPathQ0 As String
Dim QPathQ1 As String

QPathQ0 = "" 'путь к общей папке с .bas \ .cls и т.п. файлами.

Dim zQ0 As Object: Set zQ0 = CreateObject("Scripting.FileSystemObject")
Dim zQ1 As Object: Set zQ1 = zQ0.GetFolder(QPathQ0).Files
Dim zQ(0 To 1) As Object

    For Each zQ(0) In zQ1 'просматривает каждый файл в общей папке.
    QPathQ1 = QPathQ0 & zQ(0).Name
    Set zQ(1) = ThisWorkbook.VBProject.VBComponents.Import(QPathQ1) '*
    '''Select Case ?..
    zQ(1).Name = Replace(zQ(0).Name, ".", "") '*
    Next

'*: без этого - VBA импортирует их с именем по умолчанию, типа "Module1".

End Sub

Ещё не тестировал,
но идея в том, чтобы при каждом запуске документа (Excel \ Word)
- подгружать в его проект файлы из общего каталога; а при выходе из документа
- удалять их (пока тоже за кадром).

Ремарка "'''Select Case ?.."
- это недописанное условие проверки.

ДА, и у Word'а проблемы с Document_Open
- когда создаёшь документ путём запуска WINWORD.EXE (т.е., при первом запуске приложения);
мне помогла такая вот простенькая заплатка (не пугайтесь тонны текста - там, в общем-то, готовая копипаста):
https://wordmvp.com/FAQs/MacrosVBA/PseudoAutoMacros.htm
Изменено: RazorBaze - 13.12.2020 16:38:39
VBA: конфликт стандартного окна замены и Worksheet_Change
 
БМВ, если четно - просто побоялся слишком подробно расписать то,
каким образом отслеживаю изменения в колонке 1.

В реальности, там очень много скучных условий, типа:
- If Intersect(Columns(1), zChange) = Nothing ...
- Set zTarget = Union(...), и т.д.

Но к вопросу о возможности отслеживания факта использования пользователем окна замены оно отношения не имело,
так что я сократил))
VBA: конфликт стандартного окна замены и Worksheet_Change
 
БМВ, прошу прощения: события у меня конечно отключены в начале и включены в конце
- я так к этому уже привык, что просто не указал
(отредактировал первое сообщение).

Наверное так и воспользуюсь советом skais675, если мой вариант будет давать сбои.
Изменено: RazorBaze - 16.08.2018 21:56:51
VBA: конфликт стандартного окна замены и Worksheet_Change
 
skais675, про защиту знаю мало - изучу отдельно, если вариантов больше нет.

Как вариант, воспользуюсь Worksheet_Calculate:
оно выполняется ровно один раз, в конце любого количества Worksheet_Change.

Т.е., можно повесить перед Application.Undo какое-нибудь условие,
например:
Код
Private Sub Worksheet_Change(ByVal zChange As Range)
If Columns(zChange.Column) = 1 _
And QCaseReplace = 0 _
Then
QCaseReplace = 1
Application.Undo: Exit Sub
Else
End If
End Sub
- а потом "обнулить" его внутри Worksheet_Calculate,
на случай следующего конфликта замены.

Я геморройщик?
Да.
VBA: конфликт стандартного окна замены и Worksheet_Change
 
Добрый день!

У меня на единственном листе событие Worksheet_Change примерно следующего содержания:
Код
Private Sub Worksheet_Change(ByVal zChange As Range)
Application.EnableEvents = False

If Columns(zChange.Column) = 1 _
Then
Application.Undo: Exit Sub
Else
End If

Application.EnableEvents = True
End Sub
- т.е., попытка изменения данных внутри колонки 1 приводит к отмене изменений.
Так я защищаю ячейки с данными.

Было замечено, что если вызвать стандартное окно "Найти",
и произвести замену
- события Worksheet_Change начнут выполняться последовательно для ВСЕХ ячеек,
которые подошли условию замены (для 3х ячеек - 3 отдельных события Worksheet_Change, подряд).
Т.е., zChange.Count в таком случае ВСЕГДА = 1
- даже если "изменённых заменой" ячеек больше одной (!!!),
что отличает данный случай Worksheet_Change от случая удаления\переноса строк, например,
где zChange.Count был бы кратен 16384.

Проблема оказалась в том,
что если "изменённых заменой" ячеек получится ЧЁТНОЕ число
- чётное число раз подряд выполненный Application.Undo, в рамках каждого отдельного Worksheet_Change,
приведёт к тому, что изменения НЕ будут отменены
(из-за отмены "отмены" изменений).

И если в случае переноса\удаления строк, я бы мог видоизменить код следующим образом:
Код
Private Sub Worksheet_Change(ByVal zChange As Range)
Application.EnableEvents = False

If Columns(zChange.Column) = 1 _
And zChange.Count = 1 _ '<<< добавленное условие.
Then
Application.Undo: Exit Sub
Else
End If

Application.EnableEvents = True
End Sub
- позволяя, тем самым, переносить\удалять строки,
то для окна замены это снова приведёт к озвученной проблеме.

И т.д., и т.п.

...Вопрос:
есть ли способ узнать,
воспользовался ли пользователь окном замены
- ???

__________________________________________
Для решения проблемы
достаточно "перевоткнуть" (в макросе!) любую ячейку на Листе, после Application.Undo:
тогда история изменений документа обнулится, и следующую отмену выполнить не удастся!

А чтобы система не ругалась на невозможность отмены
- перед отменой поместите On Error Resume Next.

Примерно в таком виде:
Код
Private Sub Worksheet_Change(ByVal zChange As Range)
Application.EnableEvents = False

On Error Resume Next

Application.Undo (внутри условий \ как угодно)

Cells(1, 1). Value = Cells(1, 1).Value

Application.EnableEvents = True
End Sub
Изменено: RazorBaze - 23.08.2018 10:02:50
VBA - UserForm: проблема вызова Change-события объекта
 
...Обычно пока сочиняешь \ пишешь сообщение
- решения \ запросы в гугл приходят на ум сами. В смысле, ДО публикации.
Но, видимо не в этот раз :)

Короче, переключение страниц, оказывается, нехило нагружает систему,
так что лучше всего поступить следующим, прибанальнейшим образом:
Код
Private Sub UserForm_Initialize()
блаблабла
Select Case MultiPage1.Value
Case (нужное значение): Call MultiPage1_Change
Case Else: MultiPage1.Value = (нужное значение) 'MultiPage1_Change запустится автоматически.
End Select
End Sub
Изменено: RazorBaze - 15.08.2018 14:21:35
VBA - UserForm: проблема вызова Change-события объекта
 
Добрый день!

В упрощённом виде,
у меня UserForm1 содержит MultiPage1 из 2х страниц ("1" и "2"):
Код
Private Sub UserForm_Initialize()
блаблабла
MultiPage1.Value = 1
End Sub

Private Sub MultiPage1_Change
Select Case MultiPage1.Value
Case 1: блаблабла
Case 2: блаблабла
End Select
End Sub
- т.е. я хочу,
чтобы при каждой (новой) инициализации, UserForm переключал MultiPage1 на страницу "1",
чтобы второе событие - MultiPage1_Change - сделало своё не-важно-какое дело.

Проблема вылезла совершенно ЛЕВОГО характера:
оказалось, VBA отказывается запускать MultiPage1_Change,
если MultiPage1 УЖЕ находится на странице "1", ДО запуска UserForm!
И при том - НЕ где-то в памяти, а в ОКНЕ РЕДАКТИРОВАНИЯ UserForm1, открываемом из списка модулей
(не знаю, как это окно правильно называется; "View Object", а НЕ "View Code" которое; "Shift + F7" - оно же).

!!!???..

Т.е., если я в этом окне редактирования открою страницу "2", ПЕРЕД запуском UserForm
- переключение сработает! Но это [цензура]-как неудобно, ясное дело
- выставлять MultiPage на "правильную" страницу, каждый раз,
в условиях огромного количества страниц и объектов.

Переключение также сработает, если я создам 3ю, НЕНУЖНУЮ (пустую) страницу для MultiPage1 (и для многих других),
и буду скрывать её при каждом открытии, соответственно.

Приготовлю файл, если потребуется, но...
может, кто-то уже знает, как ПРИНУДИТЬ MultiPage принимать значение, которому она уже равна?
Изменено: RazorBaze - 15.08.2018 12:54:11
VBA - убрать ячейки из zRange (As Range)
 
Ігор Гончаренко, это круто))) сродни Application.Undo
хотя моё чудо мне для Worksheet_Change нужно: чтобы запретить редактировать все ячейки
- кроме тех, которые можно, с автоматической отменой действий.

Но Ваш код в работе точно будет полезен. Спасибо!

__________________________________________

2018.08.15
Благодарю sokol92 и Ігор Гончаренко за усилия по решению обозначенной в вопросе проблемы,
однако сам по себе мой вопрос всё же касался только наличия \ отсутствия стандартных экселевских функций,
выйти за рамки которых - лично я, в данном случае - категорически не готов.
Изменено: RazorBaze - 15.08.2018 11:59:52
VBA - убрать ячейки из zRange (As Range)
 
Ігор Гончаренко, написать-то я тоже написал - только не чудо получилось, а геморрой какой-то)))
Спасибо за быстрый ответ!

yozhik, боюсь, что нет: я всё-таки имел в виду что-то вроде:
Код
Set zRange = Colimns(1).EntireColumn
Set zRange = "UnUnion"(zRange, Cells(1, 1))
- чтобы эксель сам понял, что zRange у нас теперь = Range(Cells(2, 1), Cells(1048576, 1)).

Добавлю это в шапку.
Изменено: RazorBaze - 09.08.2018 16:37:25
VBA - убрать ячейки из zRange (As Range)
 
Добрый вечер!

Вот, есть у нас Union(), да? Он объединяет несколько объектов типа Range
(строго говоря, Union увеличивает количество ячеек в диапазоне, путём объединения двух изначально меньших диапазонов).

А есть ли в VBA функция уменьшения диапазонов (путём исключения меньших из большего) - ???
Было бы круто, если так же как в Union можно было бы указать условно-неограниченное число элементов.
Кроме манипуляций с Intersect, само собой.

Чтобы получилось что-то вроде:
Код
Set zRange = Colimns(1).EntireColumn
Set zRange = "UnUnion"(zRange, Cells(1, 1))
- т.е., чтобы эксель сам понял, что zRange у нас теперь = Range(Cells(2, 1), Cells(1048576, 1)).

Или я размечтался?
Изменено: RazorBaze - 09.08.2018 16:38:53
ассоциировать zTextBox (As TextBox) с другим объектом типа TextBox (на странице UserForm)
 
Nordheim, догадывался о такой роскоши, но не решался потратить время на исследование))
Большое спасибо ещё раз!

Казанский, про Object и Variant - спасибо за подсказку! В таких случаях склонен проявлять неопытность.
Про msforms.TextBox тоже соглашусь.
ассоциировать zTextBox (As TextBox) с другим объектом типа TextBox (на странице UserForm)
 
Потрясающе, Nordheim! Большое спасибо! (использовал Control)

V, вопрос-то чисто-грамматический.
Спроси я про тот же Range - Вы бы сказали "добавь Set" (если б его не было), и этого было бы достаточно.
Изменено: RazorBaze - 09.08.2018 10:15:16
ассоциировать zTextBox (As TextBox) с другим объектом типа TextBox (на странице UserForm)
 
Добрый день (ещё раз)!

Придумал хитрый план
- подглядев технологию у объектов типа Range:
Код
Private Sub MultiPage2_Change()

Dim zTextBox As TextBox

    Select Case MultiPage2.Value
    Case 1: Set zTextBox = TextBox1
    Case 2: Set zTextBox = TextBox2
    Case 3: Set zTextBox = TextBox3
    Case 4: Set zTextBox = TextBox4
    End Select

    With zTextBox
    .SetFocus
    .SelStart = 0
    End With

End Sub
...но он не сработал:
с Set'ом - возвращает "Type mismatch";
без Set'a - "Object variable or With block variable not set" (eye roll).

Хотелось, чтобы при переключении MultiPage2
- срабатывал фокус на тот, или иной TextBox, расположенный (само собой) на соответственном листе.
Ну и чтобы код был симпатичным.

Изменить "TextBox1" на "UserForm1.TextBox1" пробовал.
Пробовал также и на "Me.TextBox1": ничего не изменилось.

В Locals вообще какая-то ахинея, но типы данных вроде соответствуют.

Set, что ли, здесь неприменим?
Изменено: RazorBaze - 09.08.2018 10:01:10
Как передать объекты из UserForm в другой модуль
 
Nordheim, блин, сорри, туплю
обожаю программирование))) спасибо!
Как передать объекты из UserForm в другой модуль
 
Добрый день!

Взять условный "TextBox1".
Как перенести TextBox1.SetFocus в Sub внешнего модуля,
чтобы можно было сетфокуснуть его из UserForm?

Или они ВСЕ должны внутри UserForm находиться, слайдшоу-стайл
(внутри работет; снаружи - нет) - ???
Изменено: RazorBaze - 09.08.2018 08:35:03
Public Function возвращает, но не пересчитывает значение Public (As String) при изменении последнего
 
sokol92, и правда - вот так работает:
Код
Sub Q1()
Application.Volatile
zStr = ActiveCell.Value
ActiveCell.Value = zStr
Beep
End Sub

Только при следующем открытии книги результат не сохраняет. Но я уже всё равно через Worksheet_Change сделал.
Тему могу считать закрытой. Спасибо!
Изменено: RazorBaze - 07.08.2018 20:05:04
Public Function возвращает, но не пересчитывает значение Public (As String) при изменении последнего
 
Добрый день!

Public zStr As String = "" (при открытии файла).
Кнопочно-нажимной макрос присваивает zStr значение = ActiveCell.Value

Public Function возвращает значение zStr.
В теории.

На практике же ДАЖЕ при включённом Calculation = xlAutomatic
Public Function возвращает zStr ТОЛЬКО если нырнуть в ячейку вывода.
Т.е., автоматический пересчёт не работает.

Файл прилагаю. Незамысловатый код:
Код
Public zStr As String
Код
Sub Q1()
zStr = ActiveCell.Value
Beep
End Sub
Код
Public Function zStr_Value() As String
zStr_Value = zStr
End Function

Application.Volatile не помогает.
Видимо, поможет только Worksheet_Change.
Изменено: RazorBaze - 07.08.2018 18:22:19
объявление + присвоение значения переменной ОДНОЙ строкой
 
vikttur, спасибо))
да, я так и не прошёл полного курса программирования XD

ох, да: в первом варианте я как всегда слишком упростил.
я обычно своим переменным добавляю "Q", или "z" (ну типа как "My").
исправил!
Изменено: RazorBaze - 07.06.2018 14:50:43
объявление + присвоение значения переменной ОДНОЙ строкой
 
Добрый день, товарищи!
Имеются следующие наборы кодов:

1)
Код
Dim MyA1 As Range
Call zSearch_A1(MyA1)

2)
Код
Dim Target as Range
Set Target = Cells(1, 1)

3)
Код
Dim i As Integer
i = 1

Кто знает синтаксис - перепишите пожалуйста все 3 случая так,
чтобы 2 строки уместились в одну.

Периодически встречаю, но теперь не могу специальным образом найти
(заодно - перечислил сразу все интересующие).

Спасибо!
Изменено: RazorBaze - 07.06.2018 14:51:11
VBA - Sub прерывается до завершения без видимой причины
 
Anchoret, события у меня отключены, конечно.
Расчёты произвожу такие, что у моих строк уровень группировки задаётся соответственно значению ячейки в одной из колонок (собственно, событие Worksheet_Change). Далее, он находит все ячейки (в этой колонке со "значениями уровней") выше и ниже отредактированной, и разбивает их на списки: отдельный для всех "единиц", "двоек", "троек" и т.д. (массивы). Тогда функция максимума такого массива (при определённых условиях) будет означать, что редактируемая строка вложена (через группировку) в ту, на которую указывает функция максимума.
И если этих "максимумов" несколько (из разных списков), и если они идут по убыванию (соответственно порядковым номерам) - значит, все они вложены друг в друга, от наименьшей к наибольшей.

Sanja, я буду рад однажды поделиться со всеми интересующимимся, но в ближайшие несколько лет это будет означать нарушение неких договорённостей с моей стороны. Я не могу этого сделать.
На подготовку файла примера у меня ушло бы не меньше одного рабочего дня, что тоже нецелесообразно.

Пока не проверял советы ocet p: лучше, думаю, просплюсь сперва))

vikttur, не думаю, что кто-либо рискнул бы потратить своё время на решение незнакомых ему проблем. Тем более опираясь на их описание.
Изменено: RazorBaze - 03.05.2018 03:23:55
VBA - Sub прерывается до завершения без видимой причины
 
Ігор Гончаренко, у меня строки сгруппированы между собой, множество строк; от 1го до 7го уровня. Я их называю "паренты" и "киндеры".

Мне с детства хотелось, чтобы у каждой строки было два "адреса" (в специальных столбцах): в первый - подтягивались бы "имена" всех "киндеров", если они есть ("имя" - это тоже ячейка одного из столбцов); а в другой - "имена" всех "парентов", если они есть.

Понятно, что при каждом изменении, или перемещении (одной; нескольких строк) все эти адреса должны пересчитываться.

Далее, есть ячейка, которые ВСЕ эти имена собирает, сцеплением.
Ну и когда ты фильтруешь строки по столбцу с ячейками, куда сцеплены все имена - ты видишь не только то, что ищешь, но и всё то, что с ним связано.

И чтобы нагрузка была минимальной - составляю массивы из значений, и с ними работаю.

Освоил, блин, программирование)) вот, второй месяц мучаюсь.

Строго говоря, код работает идеально, но только для постоянно убывающих уровней.
Поэтому списков теперь не 7, а 49.
Вот-вот бы закончил. И тут - ограничения, блин.
Изменено: RazorBaze - 02.05.2018 07:50:04
VBA - Sub прерывается до завершения без видимой причины
 
Sanja, на самом деле там должно быть Dim zArr(1 to zRngCount),
но VBA почему-то её не глотает (в смысле, даже когда она уже определена)) требует, чтобы было именно число; хотя с Ubound в других случаях работает).

Прикол в том, что если сперва объявить пустой массив Dim zArr(), то потом удастся скормить ему этот "zRngCount" путём Redim zArr(1 to zRngCount). Но я не стал распространяться (в примере исправил).

А по поводу логики... да нет, знаете, там всё предельно просто, просто очень много списков и комментариев.
49 списков для изменяемой ячейки. И сопутствующих процедур (т.е., различаются они только порядковыми номерами; а так - код был бы, грубо говоря, в 49 раз короче).

А списки нужны потому что я из каждого извлекаю функцию максимума.
Изменено: RazorBaze - 02.05.2018 07:31:40
VBA - Sub прерывается до завершения без видимой причины
 
Ігор Гончаренко, я просто думал так правильнее; ну типа как без принудительного Option Explicit: можно не объявлять и не типизировать простейшие переменные... а можно всё равно это всё делать, ну вроде потому что так правильнее. "Call" я из этой логики везде писал.

Значений действительно не видно, но пустых там нигде нет!
Подчёркиваю, что без разделения на процедуры, код работал идеально (вплоть до "too large").

Но вы и не обязаны угадывать причину: я лишь надеялся, что кто-то знающий увидит неочевидное для меня ограничение, вроде того же "too large", и оно окажется причиной.

ocet p, я так расстроился из-за всего этого, что удалил всё что сделал за вчера)))
сейчас воспроизведу: скажу, помогло ли.
VBA - Sub прерывается до завершения без видимой причины
 
Добрый день!

Я передал несколько переменных из Worksheet_Change Листа:
Код
Private Sub Worksheet_Change(ByVal zChange as Range)

...

Dim zRng As Range
Dim zRngCount As Integer
Dim zArr(1 to zRngCount - предположим, что она здесь уже определена как конкретное число)


Call zCall(zArr, zRng, zRngCount)

...
((после выполнения zCall - продолжается выполнение Worksheet_Change))

End Sub

в Sub отдельного модуля:
Код
Sub zCall(zArr, zRng As Range, zRngCount As Integer)

For i = 1 to zRngCount
zArr(i) = ((присваиваю некое значение из области zRng))
Next i

End Sub

В действительности, каждой из представленных переменных несколько десятков,
и для каждой производится не одна, а множество процедур в Sub'e (в частности - не один "For", а десятки).

Проблема в том, что выполнение zCall (вызванного из Worksheet_Change) непостижимым образом прерывается, прямо посреди одного из ничем не примечательных циклов. Даже сам цикл не завершается! Выполнение Worksheet_Change продолжается, но результаты "передачи" переменных получаются неверными.

Факты могу привести следующие:
- без переноса, код работает идеально (перенос потребовался из-за возникшей на днях "Procedure too large");
- прерывание происходит тем позже, чем меньше длина массива zRng (зависит от порядкового номера строки, изменение ячейки\ячеек которой инициировало Worksheet_Change); но если редактировать одну и ту же ячейку (при прочих равных условиях), прерывание происходит в одном и том же месте;
- часть кода, которую Sub "успевает" отработать полностью (до прерывания) - даёт верный результат;
- в режиме дебаггера видно, что на некоторых "не отработанных" массивах (при наведении курсором, уже после возвращения в Worksheet_Change) висит статус "Subscript out of range";
- прерывание (в Sub'e) происходит примерно на 240-280 строке кода;
- Sub после вызова из Worksheet_Change выполняется беспрерывно, не считая причины публикации вопроса: никаких других процедур не предусмотрено, никаких условий выхода \ вызова других процедур, ничего такого;
- Excel 2013, 32 bit, сборка стандартная: плагинов \ расширений нет;
- ни на одном этапе, никаких ошибок Excel при этом не выдаёт.

Может я не верно произвожу процедуру передачи? Но об этом можно судить из оформления метода Call.
Может у Sub'ов какое-то ограничение (ну там, не знаю, по количеству итераций)? Хотя я пробовал прогнать переданную таким же образом переменную через 30000 итераций в одном-единственном цикле: всё прошло успешно.

Странно то, что прерывание может произойти ПРЯМО посреди цикла! For i, Next i, Next, Next...
А потом - БАЦ! И не дойдя до следующего "Next" (не говоря про остальные строки кода), его выкинет обратно в Worksheet_Change. И так каждый раз, и зависит - такое впечатление - только от длины zRng (т.е., в разных случаях обрываются разные циклы; хотя все они идентичны: лишь порядковые номера у заполняемых массивов разные).

К сожалению, не могу привести код целиком.

2018.05.03
Товарищи, прошу простить грешного: ошибка оказалась моя личная.
Длина одного из массивов, используемых внутри цикла, была на 1цу меньше по сравнению с длиной цикла (это правильно, не вдаваясь в подробности, с точки зрения внутренней логики).
Уж не знаю, почему, но при передаче в модуль - это вызывало крах процедуры.
До передачи же (когда ещё не было ошибки "too large") - он, судя по всему, просто дальше продолжал.

Всем большое спасибо за участие! Ваши советы и опыт всегда мне очень помогали!

2018.05.24
А ещё это говно лечится простой резолюцией где-нибудь в начале процедуры
(или перед проблемным местом):
Код
On Error Resume Next
- ибо действует только в пределах процедуры, в отличие от Application.EnableEvents
(что логично, конечно, но всё равно вымораживает), и при разделении одной процедуры на несколько - соответственно, теряется; потому он, собственно, и "продолжал" до разделения.
Изменено: RazorBaze - 24.05.2018 10:02:50
Передача\вызов переменной, обрабатываемой в Private Sub Worksheet_Change
 
Hugo, это очень похоже именно на то, что было нужно.
Большое Вам спасибо!
Изменено: RazorBaze - 30.04.2018 18:49:31
Страницы: 1 2 3 След.
Наверх