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

Страницы: 1
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
 
Добрый день!

У меня на единственном листе событие 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-события объекта
 
Добрый день!

В упрощённом виде,
у меня 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)
 
Добрый вечер!

Вот, есть у нас 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)
 
Добрый день (ещё раз)!

Придумал хитрый план
- подглядев технологию у объектов типа 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 в другой модуль
 
Добрый день!

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

Или они ВСЕ должны внутри UserForm находиться, слайдшоу-стайл
(внутри работет; снаружи - нет) - ???
Изменено: RazorBaze - 09.08.2018 08:35:03
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
объявление + присвоение значения переменной ОДНОЙ строкой
 
Добрый день, товарищи!
Имеются следующие наборы кодов:

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 прерывается до завершения без видимой причины
 
Добрый день!

Я передал несколько переменных из 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
 
Добрый день!

В свойствах Листа имею код следующего вида:
Код
Private Sub Worksheet_Change (ByVal zChange As Range)
(более 5000 строк)
End Sub

Сегодня получил ошибку "Procedure too large" при попытке запуска. Узнал об ограничении.

Суть кода в том, что если я изменяю на листе ячейку из определённой колонки (например, из колонки "1"),
то такая ячейка будет обработана (назовём её "zCell").
В частности - на основе данных этой изменённой ячейки, будет рассчитан ряд переменных:
Код
zCellUPRng As Range 
- все ячейки колонки "1" ВЫШЕ zCell.

zCellDNRng As Range 
- все ячейки колонки "1" НИЖЕ zCell.

zArrUPRowS(1 To zCellUPRng.Count)
- массив номеров строк, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.

zArrUPValueS(1 To zCellUPRng.Count)
- массив значений, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.

после этого, я разбиваю их на все ДОПУСТИМЫЕ значения (которые перед этим ограничиваю),
и составляю из них следующие списки:
Dim zArrUP8(1 To zCellUPRng.Count) 
- список номеров строк, значения ячеек которых = 8 (всего 8 списков, от 1 до 8);

получаю я его следующим образом:
For i = 1 to zCellUPRng.Count
If zArrUPValueS(i) = 8 _
Then
zArrUP8(i) = zArrUPRowS(i)
Else
End If
Next i

и далее происходит ещё много-много чего.

Таким образом, я столкнулся с проблемой перегрузки процедуры.

Пожалуйста: НЕ предлагайте введения циклов и прочих агрегаторов, вроде "With": ни один из них для меня не новость.

Я пытаюсь решить проблему путём ПЕРЕДАЧИ переменных,
в связи с чем и возник мой ВОПРОС.

Товарищ vikttur в своё время пролил мне свет на то, как можно передавать переменные между процедурами,
и\или из одного модуля в другой - за что ему отдельное спасибо, ибо с тех пор качество моей жизни значительно улучшилось)))
Однако в случае Worksheet_Change у меня возникли трудности.

Насколько я понимаю данную процедуру, весь "перенос" сводится к работе с командой "Call".
Например, в отдельном модуле определяем:
Код
Sub z_Call1(zAnotherCell As Range)
Set zAnotherCell = Cells(1, 1)
End Sub

- тогда в Private Sub Worksheet_Change я бы написал:
Код
Dim zAnotherCell As Range
Call z_Call1(zAnotherCell)

Здесь команда "Call" позволила бы мне оперировать свойствами ячейки (1, 1).

Но как мне быть в случае Worksheet_Change,
когда отдельным модулям необходимо оперировать свойствами ИЗМЕНЯЕМОЙ ячейки
- ???..

Как, например, мне перенести в отдельный модуль процесс создания одного из упомянутых выше списков:
Код
Dim zArrUP8(1 To zCellUPRng.Count) 
- список номеров строк, значения ячеек которых = 8 (всего 8 списков, от 1 до 8);

получаю я его следующим образом:
For i = 1 to zCellUPRng.Count
If zArrUPValueS(i) = 8 _
Then
zArrUP8(i) = zArrUPRowS(i)
Else
End If
Next i

- ведь вместе с ним нужно будет перенести и прочие переменные!
Код
zArrUPValueS(1 To zCellUPRng.Count)
- массив значений, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.

zArrUPRowS(1 To zCellUPRng.Count)- массив номеров строк, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.

zCellUPRng As Range - все ячейки колонки "1" ВЫШЕ zCell.

- и так вплоть до "zCell", с изменения которой и началось выполнение Worksheet_Change.

Ведь это бесконечный цикл какой-то, разве нет?
Может, есть какой-то пример, как люди справлялись с "Procedure too large", ИМЕННО в случае Worksheet_Change?
Изменено: RazorBaze - 30.04.2018 07:24:37 (приложил файл примера с работающим кодом и пояснениями к вопросу)
Обращение к переменной, содержащей порядковый номер
 
Добрый день!

Есть несколько переменных:
Код
Dim _
zArr1Max as Integer, _
zArr2Max as Integer, _
zArr3Max as Integer, _
zArr4Max as Integer

Есть ли способ обратиться к ОДНОЙ из этих переменных при условии значения ячейки от 1 до 4 ???
То бишь, если значение "1" - обращаемся к "zArr1Max"; если "2" - "zArr2Max", и т.д.

Я знаю только как вызвать конкретный ЭЛЕМЕНТ массива. Например: "Msgbox zAnotherArr(1)".
Или можно ещё так:
Код
For i = 1 to Ubound(zAnotherArr)
Msgbox zAnotherArr(i)
Next i

Вот, вопрос, собственно: можно ли как-то похожим образом обратиться к ОДНОЙ из четырёх вышеуказанных переменных, исходя из ОДНОГО из четырёх возможных значений несвязанной с ними (например) ячейки?
Чтобы получилась конструкция, вида "zArr(i)Max" - ???
получить часть строки после символов в VBA
 
Доброго дня всем!

Имею текст в ячейке, вида:
249234792762\\12412584935374\\1231242195982184\\324237423588­2358

Он служит неким адресом строки,
и я использую его в макросе.

Нужно средствами VBA (Mid? InStr? но я затрудняюсь сочинить формулу)
получить кусок строки от ПЕРВОГО знака "\\" (включительно) до ВТОРОГО "\\" (не включительно),
чтобы на выходе получилось:
\\12412584935374

вообще строки у меня бывают разные,
но во всех нужно именно от первого "\\" до второго "\\".

предполагаемый шаблон кода:
Код
Sub aaa()
Dim _
StrOld as String, _
StrNew as String
StrOld = 249234792762\\12412584935374\\1231242195982184\\3242374235882358 (или ссылка на ячейку - не важно)
StrNew = ...
Изменено: RazorBaze - 12.03.2018 11:28:52
может ли сработать Worksheet_Change при срабатывании макроса из модуля
 
Есть Sub a() в модуле:
Код
Sub a()
'
Cells(Selection.Row, 11).value = 3
End Sub

Есть Private_Sub типа Worksheet_Change на Листе (Лист в Книге всего 1):
Код
Private Sub Worksheet_Change (ByVal zChange As Range)
'
Dim _
zRng as Range, _
zCell as Range
Set zRng = [вся колонка 11]
For Each zCell in zRng
If Intersect (zCell, zChange) Is Nothing _
Then
Else
MsgBox "!!!"
End If
Next zCell

Как заставить Worksheet_Change срабатывать при выполнении макросом Sub a()
- ???
подбор значений при помощи массива VBA
 
учусь работать с массивами.
в приложенном файле имеется столбец из двоек, троек и единиц.

нужно, чтобы "For each Cell in Stolbec" (или наподобие), макрос работал с "Selection = 3" (при "Selection.Count = 1" - эти условия уже прописаны), возвращая "MsgBox" с текстом, как в образце:
- номер строки с выделенной тройкой;
- номер строки "ближайшей сверху" двойки;
- номер строки "ближайшей сверху" единицы.

предполагается объявление одного, или нескольких массивов, которые работали бы с диапазоном D1:D44, перебирая значения сверху\вниз, и каким-то образом находили именно ту двойку и ту единицу, у которых было бы максимальное значение ".Row", но не больше, чем "Selection.Row", и меньше значений ".Row" для любых других единиц и двоек  идущих после "Selection").
Изменено: RazorBaze - 24.02.2018 23:08:50
срабатывание VBA при изменении уровня группировки строк на листе
 
добрый день!

во вложенном файле, имеем прототип базы данных.
нужно средствами VBA найти способ автоматически вставлять строку ниже той, уровень группировки которой увеличивается.

целесообразность описана в файле. если сформулировать задачу совсем просто (в качестве альтернативы чтению файла) - нужно, чтобы при изменении уровня группировки ЛЮБОЙ строки на листе, Excel возвращал MsgBox "уровень строки № (номер строки) изменён".
Изменено: RazorBaze - 24.02.2018 11:33:54
Скрыть строки диапазона без пустых ячеек
 
есть код:
Код
Sub dNOhotkey5()
'
Dim r, rng, cell As Range
Set rng = Selection
    For Each r In rng
        If r.Value Like "" Then
            If cell Is Nothing Then
            Set cell = Rows(r.Row)
            Else
            Set cell = Union(cell, Rows(r.Row))
            End If
        Else
        End If
    Next r
    If cell Is Nothing Then
    Beep
    MsgBox "0"
    Else
        If cell.Count = 1 Then
        Beep
        MsgBox cell.Count
        Else
        Beep
        MsgBox cell.Count / 16384
        End If
    End If
Beep
End Sub

он в пределах выделения (Selection) считает количество строк (Row),
которые содержат хотя бы одну пустую ячейку.

в коде есть условие (If cell Is Nothing Then), которое повторяется 2 раза.

ВОПРОС. можно ли переписать код так, чтобы это условие 2 раза не повторять?
файл прилагаю.
VBA: удалить строки в Selection по условию
 
я хочу выбрать некоторое количество ячеек (одну, две, или все) в столбце B (VBA: "Selection").
пусть будет макрос, который проверит значение соседней ячейки в столбце А (VBA: Offset 0, -1).

это могут быть и другие столбцы, поэтому нужны именно Offset и Selection (или их эквиваленты, мне неизвестные).
тогда:

ЕСЛИ ячейка столбца А, соответствующая ячейке столбца B, равна "1" - вся строка удаляется целиком,
и так для каждой строки (ячейки столбца B) в Selection.

т.е., на выходе, это аналогично фильтрации (как если бы я в столбце А выбрал только нули),
но мне нужно, чтобы эксель напрочь удалял такие строки.

мой макрос работает, но только для одной ячейки, а не всего Selection :( хотя Next вроде на месте.
файл прилагаю.
Изменено: RazorBaze - 07.02.2018 18:58:25
VBA: копирование значения в соседнюю ячейку; "соседство" (право, или лево) определятся условием.
 
я собираюсь выбирать (VBA: "Selection") любое значение из колонки B.
нужно, чтобы:
если Selection.Row < 10 - значение Selection копировалось в соседнюю ячейку колонки А.
в противном случае - значение Selection копировалось в соседнюю ячейку колонки B.

и чтобы после копирования (в колонку А, или колонку B - в зависимости от Selection.Row), к результату был применён Replace (допустим, была удалена цифра "0").

файл приложен, мой код не работает.
VBA: манипуляции с переменными по условию If.
 
Если выделение (ячейка) находится ниже десятой строки - ячейка справа от неё объявляется переменной "а".
Если выше десятой строки - ячейка слева.

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

мой неработающий код:
Код
Sub a()
If Selection.Row > 10 Then
a = Selection.Offset(0, 1)
Else
a = Selection.Offset(0, -1)
End If
a.Formula = Selection
a.Replace What:=",", Replacement:=""
End Sub

я понимаю, что без файла не интересно))
но всё же, подскажите, что не так?

подозреваю, что "a.Formula" и "a.Replace" некорректны для поставленной задачи.

UPDATE
предложенные варианты не решили проблему.
решение: http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=read&FID=1&TID=101096&T...
Изменено: RazorBaze - 07.02.2018 12:24:20
глюк ФОРМУЛЬНОЙ строки при выполнения макроса экранной кнопкой (элемент управления формой)
 
в приложенном файле (можно с нуля создать свой) ячейка a1 содержит формулу,
длина которой НЕ умещается в формульной строке fx

имеется кнопка, вызывающая макрос (ЛЮБОЙ макрос; мой выполняет команду ctrl + home)
проблема возникает при выполнении макроса нажатием экранной кнопки ТОГДА,
когда выбрана ячейка, формула или текст которой не умещаются в формульной строке:
содержимое формульной строки становится искажённо-жирным.

проблема возникает даже тогда, когда макрос ПУСТОЙ! вида:
Код
sub a()
end sub

проблемы НЕ возникает, если:
1) развернуть формульную строку до ширины ДОСТАТОЧНОЙ, чтобы увидеть её содержимое целиком;
2) изначально нажать на кнопку, стоя там, где содержимое формульной строки видно без расширения;
3) перейти в режим редактирования ячейки (F2).

кроме того, проблемы НЕ возникает,
если выполнить макрос не кнопкой, а из меню макросов. или сочетанием клавиш (у меня Ctrl + й).
???
Изменено: RazorBaze - 25.01.2018 19:47:07
Применение юникода в качестве текстового условия условного форматирования
 
одна из ячеек в файле примера после применения условного форматирования (макросом) должна окраситься в красный цвет, потому что её текст содержит текст в формате юникод (грустный смайлик).

однако при попытке вставить юникод в VBA - он автоматически заменяется на "?".

при этом если узнать код конкретного символа =КОДСИМВ() - в моём случае это "63" - и попытаться заменить "?" в VBA на "Chr(63)" - условное форматирование этого не понимает, и вместо юникода - ищет "Chr(63)".
Обход ограничения \\ Каждое слово в отдельной СТРОКЕ
 
Стандартная функция Excel "Заполнить" > "Выровнять" (она же в VBA: "Selection.Justify") работает только с первыми 255 символами в ячейке, как и множество других подлых функций (например, "СЧЁТЕСЛИ").

Возможно ли обойти это ограничение?
Возможно ли написать пользовательскую функцию?
Может есть вообще другой способ?

Задача: преобразовать текст в ячейке таким образом, чтобы рядом с ним создалось количество строк, равное количеству слов в ячейке (по факту - количеству пробелов между словами, +1).
Чтобы у каждого слова из первоначальной ячейки была своя собственная строка. Вот так:
Чтобы
у
каждого
слова
из
первоначальной
ячейки
была
своя
собственная
строка.
Вот
так:

(а потом я ещё всякие символы лишние, вроде ":" и "." убираю).
"Текст по столбцам" не предлагать.
Спасибо.
Изменено: RazorBaze - 09.09.2017 11:24:43 (Прикреплён файл примера.)
Оптимизация времени пересчёта ячеек, на которые ссылаются формулы
 
Таблица примерно 10,000 строк на 1,000 столбцов. С каждым годом будет примерно вдвое больше.
Ячейки 800 из 1,000 столбцов так или иначе ссылаются друг на друга. У формул очень сложные условия (до десятков "ЕСЛИ"), причём я задавал их таким образом, чтобы каждый столбец сперва проверял значение ПЕРВОГО - самого главного в иерархии - столбца. Выглядит это примерно так:
=ЕСЛИ(А1="";"";ЕСЛИ(ЕСЛИ(ЕСЛИ(...))), - т.е., если ячейка первого столбца пустая, то формула возвращает пустое же значение, и ресурсы на проверку остальных условий не расходуются.

Всё это делалось с целью уменьшения времени пересчёта всех этих десятков условий. Однако проверка специальным калькулятором пересчёта показала, что эксель дольше всего "думал" не над "формульными" ячейками, а над тем самым "главным" столбцом А1, на который ссылается большинство формул. Причём ячейки столбца А1 не содержат вообще никаких формул. Только текстовые значения (или их отсутствие, "пустоту").

"Application.Calculation = xlManual" помогает, но при включении "автомата" (или там, сохранении) пересчёт происходит слишком долго.
Может быть есть какое-то более сильное колдунство?
Изменено: RazorBaze - 31.08.2017 19:59:49
Выпадающий список во время редактирования ячейки
 
Все знают, что если начать ячейку с "=",
а следом ввести букву (например, "Е") - появится список функций,
начинающихся на эту букву:
- ЕОШИБКА
- ЕСЛИ
- ЕСЛИПУСТО
- ЕССЫЛКА
- ЕТЕКСТ
- ЕЧИСЛО, и т.д.

При этом, если после "Е" поставить букву "С" - все несовпадения отсеются,
и останутся только:
- ЕСЛИ
- ЕСЛИПУСТО
- ЕССЫЛКА, и т.д.
Такой же список, только с другими вариантами выбора, выпадает в VBA, когда начинаешь ввод любой его функции.

Вопрос. Можно ли средствами VBA, или любыми другими средствами, сделать похожий список для другого символа?
Например, чтобы при вводе кавычки (") - выпадал бы список неких вариантов, и при наборе букв - несовпадения автоматически отсеивались бы, аналогично списку формул?
А перечень вариантов чтобы задавался диапазоном ячеек, как при "проверке данных".
При этом хотелось бы, чтобы такой список выпадал при всяком вводе кавычек ("), а не только в начале.
Изменено: RazorBaze - 15.07.2017 10:45:05
Синхронизация диапазонов по шаблону
 
Здравствуйте.

В приложенном файле представлены объекты "А", "Б" и "ШАБЛОН". Каждый из них характеризуется свойствами 1 и 2.
Задача: при добавлении строки "Свойство 3" для объекта "ШАБЛОН", такая же строка должна появиться у объектов "А" и "Б".

Дополнительные условия:
1) Любые изменения свойств объекта "ШАБЛОН" (например, изменение названия "Свойство 3" на "Продолжительность") должны "синхронизироваться" с остальными объектами.
2) При удалении строки "Свойство 3" у объекта "ШАБЛОН", а также при удалении любой другой строки, должны удаляться соответствующие строки и у остальных объектов.
3) Иерархия документа пострадать не должна. Желательно.
Страницы: 1
Наверх