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

Страницы: 1 2 3 4 5 6 След.
Сохранение значения UDF
 
Доброго времени суток, уважаемые форумчане. Вновь обращаюсь к вам за помощью в написании кода, ситуация такая: имеется код наполнения словаря:  
Код
 For i = 1 To UBound(xF)
    n = Calc_NR(dicNum, xF(i, 1) & "|" & xF(i, 4))
    dicData.Item(Join(Array(n, xF(i, 6), xF(i, 3)), "|")) = xF(i, 2)
 Next i
в силу определенных обстоятельств, мне требуется расчет для нумерации по строкам (n) для каждого расходного документа, делать я это попытался с помощью функции пользователя:
Код
Function Calc_NR(dicNum As Object, key As String) As Long 'расчет нумерации реестра
    If dicNum.Exists(key) Then
        Calc_NR = Calc_NR + 1
    Else
        dicNum.Item(key) = 1: Calc_NR = 1
    End If
End Function
Частично получилось, но возникли 2 вопроса: функция верно рассчитывает номер для первой позиции, но не сохраняет значение Calc_NR для 2-ой и последующих позиций, все они нумеруются как 1. Можно ли, и как, если можно, это исправить? и второй вопрос (с разрешения модераторов) можно ли и как, если можно, напрямую использовать функцию при формировании ключа словаря, т.е. записывать не  
Код
dicData.Item(Join(Array(n, xF(i, 6)...
а так:
Код
dicData.Item(Join(Array(Calc_NR, xF(i, 6)...
при условии конечно, что есть решение для первого вопроса, а иначе зачем?
Заранее спасибо всем откликнувшимся
Пакетная отправка файлов через CDO
 
Доброго времени суток, уважаемые форумчане. Я уже поднимал тему отправки файлов через  CDO на нашем форуме, но вопрос возник снова. Итак, в функцию отправки письма передается словарь, ключом которого является адрес, а итемом - массив наименований документов к тому времени уже созданных. Словарь (для примера конечно) наполняется так:
Код
        For i = 1 To 2
            If Not dicMail.Exists(Key) Then
                dicMail.Item(Key) = Cells(i, 1).Value & ".pdf"
            Else:
                dicMail.Item(Key) = Array(dicMail.Item(Key), Cells(i, 1).Value & ".pdf")
            End If
        Next i
ad = Func_SendMailCDO(dicMail)
далее вызов функции, инфа по логину-паролю, разумеется левая, для примера:
Код
Function Func_SendMailCDO(dicMail As Object) 'отправка на e-mail покупателя
    Dim objCDOCnf As Object, objCDOMsg As Object, att As Variant, k As Variant
        Const CDO_Cnf = "http://schemas.microsoft.com/cdo/configuration/"
        Set objCDOCnf = CreateObject("CDO.Configuration") 'назначаем конфигурацию CDO
        
            With objCDOCnf.Fields
...
                .Item(CDO_Cnf & "sendusername") = "login@mail.ru" 'учетная запись на сервере
                .Item(CDO_Cnf & "sendpassword") = "pass" 'пароль к почтовому аккаунту
                .Update
            End With
                    
            On Error Resume Next
            For Each k In dicMail.keys
                Set objCDOMsg = CreateObject("CDO.Message") 'создаем сообщение
                With objCDOMsg
...
                    .Subject = "Копии документов" 'тема письма
Далее я пытаюсь прикрепить аттач и вот с этим у меня и возникают проблема, т.к. само письмо уходит по адресу и вообще, кроме аттача, код отрабатывает на ОК:                    
Код
For Each att In dicMail.Item(k)
         .Attachments.Add ThisWorkbook.Path & "\" & att
         Kill ThisWorkbook.Path & "\" & att
Next att
       .Send
значение att верное, файлы pdf в наличии, а значение objCDOMsg.Attachment.Count как было =0 так и остается. Повторюсь, письмо уходит, но пустое без нужного вложения. Что сейчас написано не так и как это исправить?
Заранее спасибо всем откликнувшимся.
Функция пользователя: ввод параметров
 
Доброго времени суток, уважаемые форумчане. Пытаюсь "допилить" под себя функцию пользователя, найденную на просторах сети и вот вылезли небольшие вопросы. Скажу сразу, код работает, но хотелось бы узнать можно ли написать по-иному, с моей точки зрения красивее и правильнее. Итак, огрызок функции (в ячейке В1):
Код
Function test(CaseWord As Byte, Surname As String, Optional Name As String, Optional Patronymic As String) As String
    tmp = Mid(Array(Surname, Name, Patronymic)(i), 1, Len(Array(Surname, Name, Patronymic)(i)) - 1)
    'склонение фамилии
    t1 = tmp
    i = i + 1
    'склонение имени
    t2 = tmp & 123
End Function

имеем переменную tmp, которая принимает значение в зависимости от значения i. Используем эту переменную, далее меняем значение i, и хотелось бы, чтобы значение переменной изменилось бы при расчете склонения имени само, без дополнительной команды. Возможно ли это? Сейчас, разумеется, значение tmp просто перезаписывается отдельно.

Заранее спасибо всем откликнувшимся

Текст между скобок регулярными выражениями
 
Доброго времени суток, уважаемые форумчане. Никак не могу разобраться с особенностями синтаксиса регуляров и поэтому вновь обращаюсь в вам за помощью в решении задачи. Итак, ситуация по идее простая: имеется текст типа 123(999), требуется извлечь данные, находящиеся между скобок, т.е. 999. Сделать это обязательно регулярами (причина требования к вопросу не относится). Казалось бы, чего сложного, паттерн "\d+" и второй item и все ОК, но нет. Дело в том, что скобок в данных может и не быть, будет любое число, а в таком случае RegExpExtract выдаст ошибку #ЗНАЧ! Любые проверки на наличие скобок, не то чтобы запрещены, но в таком случае ни о каком сокращении объема кода речь не идет, а именно это и является задачей. Итак, можно ли решить данный вопрос, т.е. извлечь одним регулярным выражением нужный текст (из ячеек А1 и В1 прилагаемого файла) и, если да, то как?

P.S. Заранее спасибо всем откликнувшимся
Изменено: OlegO - 20.11.2024 14:30:33
Доступ к item-ам регулярного выражения
 
Доброго времени суток, уважаемые форумчане. В предыдущей теме, поднятой мною на форуме:https://www.planetaexcel.ru/forum/?PAGE_NAME=read&FID=1&TID=167725&TITLE_SEO... вопрос, как мне хотелось решить не удалось. Но возникла мысль по другому варианту его решения 8-0, итак:
Код
    Dim v_RegExp As Object, s As String
        Set v_RegExp = CreateObject("VBScript.RegExp")
            s = "2;2;222;202:5;155545;25;6:3;13;13;89"
            v_RegExp.Pattern = ":"
            v_RegExp.Global = True
            f = v_RegExp.Execute(s).Item(0).FirstIndex '11
            
            ff = InStr(s, ":5;") - 1 '11
Мы имеем строку с выражением, разделенным на 3 "куска" двоеточиями (в оригинале это массив, хранящийся в диспетчере имен). Через свойства
FirstIndex мы можем получить данные о расположении паттерна (в примере 11 и 25). Теперь вопрос: можно ли и как, если можно, получить информацию о FirstIndex для всех item, сколько бы их не было (много их не будет, но 10-20 может быть), типа как в словаре обращаемся к dicData.items? По задумке, если вышенаписанное реально, то найдя в строке положение нужного мне блока символов (в примере ":5; (такой вариант будет уникальным)) я бы мог найти это значение в "коллекции значений" FirstIndex и узнать (тоже правда пока не знаю как) номер итема для этого значения и задача для меня решится.

Заранее спасибо всем откликнувшимся, а если кто нибудь, прочитав предыдущую тему, предложит решение там ,то размер моего спасибо будет не меньшим ;)  
Изменено: OlegO - 07.10.2024 17:41:05 (орфографическая ошибка)
Pattern для регулярного выражения
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, как нужно указать pattern для регулярного выражения.
Итак, есть срока следующего вида: 2;0;0;44;0;0;1;0;0;0;0;1;0:1;0;0;0;2;0;2;0;0;0;0;0;0:44;0;0;0;4;0;4;0;0;0;10;0;0
Необходимо создать pattern для выделения части текста, отмеченной красным, при этом эта самая часть может быть как в середине текста, так и в начале: 1;0;0;0;2;0;2;0;0;0;0;0;0:2;0;0;44;0;0;1;0;0;0;0;1;0:44;0;0;0;4;0;4;0;0;0;10;0;0 или в конце: 2;0;0;44;0;0;1;0;0;0;0;1;0:4;0;4;0;0;0;10;0;0:1;0;0;0;2;0;2;0;0;0;0;0;0 Положение не связано ни с чем, оно просто есть, главным признаком нужного фрагмента является 1-я цифра в блоке (в примере 1). Так вот, pattern для варианта начала у меня вроде получился: ^1[;][^:]+ результат в ячейке А8 правильный. А вот для 2-х других вариантов: :1[^:]+ получается не совсем правильно: :1;0;0;0;2;0;2;0;0;0;0;0;0, т.е. в начале находится ненужное двоеточие. Как  мне следует исправить pattern, чтобы этого не было? Эти паттерны планирую использовать через признак ИЛИ, так что, если для 3-х вариантов нужно 3 паттерна - значит будут.
Заранее спасибо всем откликнувшимся.

P.S. Что касается получившегося паттерна, то, если по мнению настоящих гуру он требует переделки или доводки, то рад буду увидеть варианты от Мастеров
Изменено: OlegO - 05.10.2024 17:28:24
Замена указанного символа в строке
 
Доброго времени суток, уважаемые форумчане. Ситуация у меня может и простая. а найти решение не могу :oops: . Итак, есть строка типа 1;0;0;0;0;0;0;0;0;0;0;0;0, необходимо кодом заменить скажем 4-ю цифру (для примера), чтобы получить значение например: 1;0;0;9;0;0;0;0;0;0;0;0;0. Когда я пытаюсь сделать это через replace, то либо меняется только 1-ый ноль (если конечно при этом указываю, что замен нужно только 1), либо (если указаваю позицию старта), то обрезается строка до нее (как ей и положено). Как можно кодом решить эту проблему?
Заранее спасибо всем откликнувшимся
Фильтрация в диспетчер имен
 
Глубокоуважаемые форумчане, доброго времени суток. Позвольте еще раз поднять тему с вопросом, который уже имеет решение, но мне интересно, имеется ли альтернативное. Итак, по ходу выполнения кода требуется пересчитать диапазоны в диспетчере имен:          
Код
    For Each n In ActiveWorkbook.Names 'перерасчет диапазона для диспетчера имен
      If Mid(Split(n.Value, "!")(0), 3, Len(Split(n.Value, "!")(0)) - 3) = "КП арендаторов"  Then n.Value = Left(n.Value, InStrRev(n.Value, "$")) & Cells(Rows.Count, 1).End(xlUp).Row
    Next n
т.е., как видим, если выполняется условие имени листа, выполняется команда. А вопрос вот какой: можно ли отфильтровать имена для ActiveWorkbook.Names (для примера задав фильтр как "КП арендаторов") по аналогии с фильтрацией массива? Повторюсь, не то чтобы жизненно важно было имеется ли такое решение, но знать можно ли так, я бы хотел. Я вижу, что тип для ActiveWorkbook.Names показывается как Object/Names и вариант "в лоб"
Код
For Each n In Filter(ActiveWorkbook.Names, "КП арендаторов")
не проходит, но вдруг просто делаю я это не так, а написав иначе это можно выполнить?

Заранее спасибо всем откликнувшимся.
 
Копирование диапазона с пересчетом формул, требуется "размножить" диапазон
 
Доброго времени суток, уважаемые форумчане. Скажу сразу, пытаюсь найти альтернативное решение вопроса, чисто для самообразования. Итак: имеется диапазон ("A1:D2"), содержащий и данные и формулы (для примера самые простые). Требуется размножить этот диапазон скажем еще на 6 строк. Пытаюсь сделать это следующим кодом
Код
Range("A4:D9").Value = Range("A1:D2").FormulaR1C1
но, тогда как в первых 2 строках нового диапазона все в порядке (данные копируются, ссылки в формулах пересчитываются) , в остальных строках выходит ошибка.
Разумеется, я знаю, что можно выделить исходный диапазон, скопировать его и вставить в новый, но повторюсь про альтернативное решение (если оно есть конечно)
Подскажите можно ли решить данный вопрос именно таким способом и как?
Заранее спасибо всем откликнувшимся.
Работа с отфильтрованным словарем
 
Доброго времени суток, уважаемые форумчане. Возник небольшой вопроси, если на него есть решение, то буду очень рад его увидеть. Итак, наполняется словарь: в ключах названия, в итемах количество:    
Код
Dim dicData As Object, i As Long, Data As Variant, Data2 As Variant
    Set dicData = CreateObject("Scripting.Dictionary"): dicData.CompareMode = 1
        
        For i = 1 To 5
            dicData.Item(Cells(i, 1)) = Cells(i, 2)
        Next i
            Data = Filter(dicData.keys, "р", , vbTextCompare)
затем я отфильтровываю нужные мне значения. Все ОК, но можно ли и как, если можно, получить доступ и итемам отфильтрованных данных, чтобы иметь возможность подсчитать сумму аналогично Application.Sum(dicData.items), причем сделать это БЕЗ цикла (как в цикле я знаю). Не то чтобы мне мешал цикл или что-то другое, просто я предположил, что если VBA  может отфильтровать данные словаря, то может и итемам отфильтрованных данных может получить доступ сразу, без цикла? Повторюсь, вопрос для самообразования, если такое невозможно, вопросов никаких быть не может 8-0

Заранее спасибо всем откликнувшимся
Отправка почтового сообщения, используя CDO, макрос работает только для почтового сервера
 
Доброго времени суток, уважаемые форумчане. Вынужден вновь поднять свою же тему 2021г.: https://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=137635&a.... Тогда вопрос был частично решен советом от уважаемого Андрей VG да и, самое главное, пользователь передумал в своих желаниях. Сейчас пользователь сменился и вопрос вновь возник. Напомню, я пытаюсь отправлять почтовое сообщение, используя следующий макрос: https://www.excel-vba.ru/chto-umeet-excel/kak-otpravit-pismo-iz-excel/. В прилагаемом файле указаны логин и пароль для 2 почтовых серверов. Проблема в том (можно убедиться, указав в ячейке В2 любой существующий ящик) что для yandex.ru все работает (совет от Андрея:
  1. Откройте раздел «Почтовые программы» в настройках Яндекс Почты.
  2. Обязательно выберите опции Разрешить доступ к почтовому ящику с помощью почтовых клиентов → С сервера imap.yandex.ru по протоколу IMAP и Пароли приложений и OAuth-токены.
  3. Сохраните изменения.
выполнен), тогда как для mail.ru код макроса сообщает об ошибке: отказ сервера SMTP. Аналогичных настроек для mail.ru я не нашел, доступ к почте по IMAP, POP и SMTP во  внешних сервисах включен. В инете были советы по похожей проблеме об использовании пароля для внешних приложений, но это не помогло (в тестовом ящике такого пароля нет, так как от требует указания реального телефона, но на своем реальном адресе я проверял эту возможность). Уважаемые гуру, подскажите как все таки можно решить эту проблему хотя бы для mail.ru (рабочий ящик на нем), можно ли указать нужные настройки (как в совете от Андрея) в теле самого макроса?

Заранее спасибо всем откликнувшимся.
Функцию СМЕЩ в код VBA, Адаптировать результат формулы
 
Доброго времени суток, уважаемые форумчане. Пытаясь "оптимизировать" код, столкнулся с небольшой проблемкой. Скажу сразу, сейчас есть готовое решение и, если не будет другого, ничего страшного. Итак, имеется список арендаторов, среди данных которых есть и номера их телефонов. Требуется подсчитать их кол-во у каждого. Сейчас я делаю это, используя Application.CountA, при этом для указания диапазона требуется вычисление нужной строки через Application.Match, что немного громоздко и неудобно читается, т.к. вычисленное значение лишь одно из необходимых для расчета. Формулой эту задачу я смог решить более коротко: =СЧЁТЗ(СМЕЩ(A10;0;4;;3)), где А10 - нужный арендатор, но при попытке адаптировать формулу в код, увидел, что offset имеет только 2 аргумента, а аргументы высоты и ширины из формулы отсутствуют. Можно ли обойти этот момент в коде? Или еще как-нибудь указать диапазон для CountA, вычислив нужную ячейку только 1 раз?  Еще раз прошу прощения, что прошу помощи, имея готовое решение, но знания других вариантов не могут быть лишними как мне кажется
Заранее спасибо всем откликнувшимся.  
Сложный фильтр в словаре VBA
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, как (и можно ли) решить данный вопрос. Скажу сразу, рабочее решение есть, просто пытаюсь придумать 2 вариант для (самообразования). Итак, словарь наполняется:    
Код
Dim dicData As Object, key As String, i As Long, kt As Variant
        Set dicData = CreateObject("Scripting.Dictionary"): dicData.CompareMode = 1
                        
            For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
                key = Join(Array(i, Cells(i, 1), Cells(i, 2)), "|")
                dicData.Item(key) = Cells(i, 3)
            Next i
далее требуется получить данные из этого словаря (в рабочем файле это делается циклом, а сейчас пытаюсь сделать фильтром:
Код
            k = 5 & "|" & 123456 & "|" & 123456
            
            For Each kt In Filter(dicData.keys, Split(k, "|")(2) & "|" & Split(k, "|")(2), , vbTextCompare)
                res = dicData.Item(kt)
            Next kt
здесь все считает правильно. Чуть поясню по структуре данных, в словарь попадают: порядковый номер, номер счетчика и его индекс. Индексом является номер головного счетчика к которому присоединены прочие. Таким образом для получения значения  "головного " счетчика подходит фильтр Split(k, "|")(2) & "|" & Split(k, "|")(2) и, повторюсь, здесь ошибки нет. А вот для расчета значений остальных значений счетчиков, присоединенных к головному фильтр указать не получается. Фактически нужно указать любое значение Split(k, "|")(1) & "|" & Split(k, "|")(2) или вообще любое значение  & "|" & Split(k, "|")(2)  Пытался сделать "в лоб":
Код
            For Each kt In Filter(dicData.keys, "*" & "|" & Split(k, "|")(2), , vbTextCompare)
                sum = sum + dicDataTemp.Item(kt)
            Next kt
но не выходит. Так вот, если можно сразу 2 вопроса по теме: как это сделать и, если можно, как это сделать за 1 цикл (про цикл не так важно, просто интересно)
Заранее спасибо всем откликнувшимся
Функция CountIf для ключей словаря
 
Доброго времени суток, уважаемые форумчане. Давно не обращался на наш форум со своими "хотелками", как-то сам справлялся ;) , но вот вылез маленький вопросик. Итак, имеем массив в котором ключами являются даты:  
Код
 Set dicData = CreateObject("Scripting.Dictionary"): dicData.CompareMode = 1
    x = Range("A1:B" & Cells(Rows.Count, 2).End(xlUp).Row).Value
        For i = 1 To UBound(x)
            dicData.Add x(i, 1), i
        Next i
Все ОК, но ХОТЕЛОСЬ бы в готовом словаре, причём обязательно БЕЗ ЦИКЛА получить кол-во ключей, удовлетворяющих условию (в примере дата должна быть сентябрьской). Пытался сделать так:
Код
ss = Application.CountIf(dicData.keys, "??.09.2022")
не выходит, ругаться на код не ругается, но значение ss становится типа массивом и значением каждого элемента Error 2015. Можно ли решить данный вопрос именно так, т.е. самое главное без цикла или нет? Если нет, ничего страшного, сейчас вопрос уже имеет решение.

Заранее спасибо всем откликнувшимся.
Параметры листа макросом
 
Доброго времени суток, уважаемые форумчане. Давно не обращался за помощью на наш уважаемый форум, как-то получалось самому решать текущие вопросы, но все-таки вопрос появился. Самое главное, вопрос пока чисто теоретический. Итак, ситуация такова: пользователь теоретически может "испортить" лист документа (удалить формулы и текст, изменить высоту и ширину строк и т.д.). Для решения этой гипотетической ситуации сейчас в документе присутствуют резервные листы на основании которых макросом восстанавливаются "испорченные". А теперь наконец вопрос. Можно макросом создать лист и прописать все необходимые данные (формулы, текст в нужных ячейках со всеми параметрами шрифта, параметры строк и колонок и т.д.) А вот можно ли и как сделать это (получить необходимые данные) макросом? Т.е. оформленный лист "просканировать" и получить в итоге все данные об этом листе. А для восстановления листа использовать следующий алгоритм: создать лист и вставить данные из БД (где-то описанной) о его параметрах. Вопрос, повторюсь, чисто теоретический, нет значит нет, останется прежний вариант и все.
Заранее спасибо всем откликнувшимся.
Использование словаря словарей
 
Доброго времени суток, уважаемые форумчане. Вновь хотелось бы узнать от гуру форума можно ли сделать так как я хочу. Вопрос, скажу сразу, пока чисто теоретический, в реальном файле все решается немного по другому. Итак, в ячейках имеется информация (дата, наименование товара, кол-во и цена). Также в столбце Е может иметься один из 2 признаков для отбора ("В" или "ОК") или не иметься, и это тоже признак. Далее, в найденных на просторах сети примерах использования словаря словарей в случае ненахождения ключа создается новый словарь:
Код
If Not Dic.exists(t) Then 'если ещё нет ключа
   Set Dic2 = CreateObject("Scripting.Dictionary"): Dic2.CompareMode = 1 'создаём субсловарь
...
А мне, если конечно я правильно рассуждаю, хотелось бы видеть приблизительно следующее. С самой первой строки данных (принцип отбора по дате опустим) первый ключ (данные столбца Е, в примере в ячейке Е2 пусто) разумеется будет отсутствовать в словаре и должен создаться субсловарь для такого варианта ключа, затем этот субсловарь наполняется нужными данными. Далее переходим к ячейке Е3, там также нет данных (напомню это тоже вариант отбора), извлекаем созданный субсловарь и вносим в него соответствующие данные. Переходим к ячейке Е4, там есть признак ОК, значит создаем еще один субсловарь, теперь для такого варианта ключа и наполняем его. Далее проверяем данные дальше наполняя соответствующие субсловари, дойдя до ячейки Е12 создаем последний вариант субсловаря (с признаком В) ну и разумеется наполняем и его. Таким образом по моей задумке после завершения отбора данных мы должны получить словарь из 3 ключей в итемах которых будут находиться данные 3 субсловарей с отобранными данными. Я буду знать размерность этих субсловарей, а это пригодится мне при выгрузке данных. Прошу прощения за "многобуквенность" и самое главное за возможную ересь самого предложенного способа, но ведь не спросив, не узнаешь.
P.S. заранее спасибо всем откликнувшихся
Изменено: OlegO - 26.05.2021 19:00:28
Фильтрация в словаре
 
Доброго времени суток, уважаемые форумчане. Скажу сразу, вопрос больше теоретический, так как готовое решение уже есть, но хочется узнать можно ли решить это иначе. Итак, ситуация: имеется словарь dicData, в ключах которого находится информация типа:
"Яшин О.Р.|03.03.2021|"
"Шестаков Н.В.|05.03.2021|"
"Шестаков Н.В.|05.03.2021|ОК"
"Андреев А.Э.|29.03.2021|В"
Поясню, в конце ключа может быть признак (В или ОК) или не быть ничего и это тоже является признаком для последующего отбора. Для выборки из словаря необходимой информации, пытаюсь применить фильтр:
Код
For Each k In Filter(dicData.keys,  "|ОК", , 1)
...
Для вариантов с признаком понятно: "|ОК" или "|В", а вот можно ли указать для фильтра именно отсутствие признака? Если использовать "|", то фильтр фактически не работает, ведь такой символ есть в каждом ключе (можно конечно проверить ниже в коде If Split(k, "|")(2) = "" Then, но тогда это будет работать только для отсутствия признака, а я пытаюсь "сваять" универсальный вариант с минимумом строк (чисто для самообразования). Сейчас это решается тройным прогоном по массиву данных с советующим условием (нет признака или указан определенный).
P.S. Заранее спасибо всем откликнувшимся
Изменено: OlegO - 15.05.2021 20:20:31
Изменение цвета фона для большого кол-ва ячеек
 
Доброго времени суток, уважаемые форумчане. Не могу разобраться с проблемой , помогите, если можно. Итак, по ходу выполнения кода, переменная  cell_close принимает значение типа  "E62,E61,E13,E15,E7,E48,E10..." Таких адресов ячеек в реальном файле сейчас пару тысяч, а будет еще больше. Далее вышеперечисленные ячейки должны закраситься:
Код
Range(cell_close).Interior.Color = 255
НО тут и вылезает проблема. Когда тестил код, таких ячеек было с 10 и все работало правильно, а вот в реальном файле, код начинает ругаться: method range of object worksheet failed В прилагаемом файле переменная содержит 64 адреса и код не работает, стоит уменьшить до 61 и код срабатывает как надо. Я, так понял, превысил какое-то ограничение на кол-во адресов ячеек? Можно ли это как то обойти, если конечно дело в этом? В реальном файле, повторюсь, таких адресов будет несколько тысяч
P.S. Заранее спасибо всем откликнувшимся
Изменено: OlegO - 12.05.2021 20:30:14
Поля страницы при использовании .PrintForm
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, можно ли решить данный вопрос. Итак, имеется UserForm, которую необходимо распечатать. Делаю я это через .PrintForm. Все работает, НО форма имеет скорее альбомную ориентацию и поэтому печатается на листе совершенно без полей. Отсюда вопрос: можно ли и как, если можно, указать что лист для печати требуется сориентировать как альбомный (ведь мы не указываем на каком листе это делать, это же некий "виртуальный" лист?), ну и указать параметры полей этого листа. Как это сделать? В прилагаемом файле PDF пример печати формы на виртуальном принтере.

P.S. Заранее спасибо всем откликнувшимся
Печать колонтитулов через VBA
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, ответ на небольшой вопрос. Итак, ситуация: необходимо в колонтитул листа вывести информацию (сумму по странице) . Для теста (код выведен на кнопку) я попытался сделать это так:
Код
    Dim HPB As HPageBreak, rngHPB As Range, sum_page As Double, i As Long, j As Long
        If ActiveSheet.Name = "Остатки на складе" Then 'обязательно условие - указание имени листа, иначе VBA пытается выполнить код на др. листах
            With Sheets("Остатки на складе")
'                If .HPageBreaks.Count > 0 Then
                    Set rngHPB = .HPageBreaks(.HPageBreaks.Count).Location
                    i = 8
                    
                    For Each HPB In ActiveSheet.HPageBreaks
                        j = j + 1
                        Set rngHPB = HPB.Location
                        sum_page = Application.Sum(.Range(.Cells(i, 9), .Cells(HPB.Location.Row - 1, 9)))
                        If sum_page > 0 Then
                            i = HPB.Location.Row
                            .PageSetup.RightFooter = Join(Array("Итого по стр. ", j, Space(1), Format(sum_page, "0.00")))
                            .PrintOut From:=j, To:=j, Copies:=1, Collate:=True
                        Else: Exit Sub
                        End If
                    Next HPB
'                End If
            End With
        End If
Может и не совсем оптимально придумал (критика и оптимизация кода приветствуются ;) ), но код работает. НО когда я попытался перенести его в событие Workbook_BeforePrint(Cancel As Boolean), то ничего не вышло, точнее вышло да не так: печатаются все 19 из требуемых (в данном примере) 4 страниц и сумма в колонтитулах ставится одинаковая для всех страниц (по 4 странице). Почему так получается и что надо изменить в коде, чтобы исправить эту ошибку?
Заранее спасибо всем откликнувшимся
Поиск номера позиции элемента, заданного по маске, в массиве
 
Доброго времени суток, уважаемые форумчане. Снова обращаюсь в вам за АЛЬТЕРНАТИВНЫМ решением задачи для самообразования. Итак ситуация: имеется массив данных: Arr_fuel = Array("бензин", "топливо", "газ"). Требуется проверить содержимое активной ячейки на совпадение с элементами массива, при этом содержимое ячейки может иметь вид "Газ углеводородный СПБТ", но главное слово здесь это газ, проверять на совпадения нужно по маске и такой вариант должен считаться как совладение. При этом для дальнейших расчетов требуется запомнить номер элемента найденного совпадения в массиве. Сейчас все это РАБОТАЕТ так:
Код
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Arr_fuel = Array("бензин", "топливо", "газ")
    For j = 0 To UBound(Arr_fuel)
        If UCase(ActiveCell.Value) Like UCase("*" & Arr_fuel(j) & "*") Then Exit For
    Next j
                    
    If j <= UBound(Arr_fuel) Then
        x = Range("A1:C" & Cells(Rows.Count, 1).End(xlUp).Row).Value
                            
        For i = 1 To UBound(x)
            If UCase(x(i, 1)) Like UCase("*" & Arr_fuel(j) & "*") Then MsgBox "ДА  " & Arr_fuel(j)
        Next i
    Else: MsgBox "НЕТ"
    End If
End Sub
А вопрос у меня такой: можно ли найти значение j БЕЗ использования цикла. Повторюсь, рабочее решение у меня есть, просто хотелось бы узнать о возможности альтернативного решения, чисто для опыта. Если такого решения нет, ничего страшного, нет так нет.
Заранее спасибо всем откликнувшимся
Определить в какой диапазон попадает дата
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, есть ли АЛЬТЕРНАТИВНОЕ решение данной задачи. Итак, имеется массив с датами и соответствующими вариантами ответов:
Дата введенияНомер приказаВариант
25.10.2020 зимняя
01.03.2021 летняя
20.10.2021 зимняя
01.04.2022 летняя
требуется определить в какой диапазон попадает искомая дата (например 01.01.2021) и выдать соответствующий результат. Решаю я это сейчас циклом:
Код
    WS = Range("A2:C" & Cells(Rows.Count, 1).End(xlUp).Row).Value
        For i = UBound(WS) To 1 Step -1
            If WS(i, 1) <= [E2] Then
                MsgBox WS(i, 3): Exit For
            End If
        Next i
Все работает, считает правильно, но возник вопрос или даже скорее "хотелка", можно ли получить тот же результат НЕ ПРИМЕНЯЯ цикл? Просто эти данные нужны при наполнении словаря и "каждоразовый" цикл выглядит немного некрасиво. Повторюсь, готовое рабочее решение есть, хотелось бы знать есть ли другое.
Заранее спасибо всем откликнувшимся
Повторное использование строк кода
 
Доброго времени суток, уважаемые форумчане. Хотелось бы узнать ответ на чисто теоретический вопрос. Итак, ситуация такая: имеется наполненный словарь с данными и значение переменной, начинаем наполнять итоговый массив:                  
Код
Arr_Mem = Array("аренда", "коммерческий") 'первоначальное значение переменной 

ReDim Arr_data(1 To dicData.Count, 1 To 7) 'формирование итогового массива
      For Each k In dicData.keys
          If IsNumeric(Application.Match(dicData.keys()(1), Arr_Mem, 0)) Then
             j = j + 1
             Arr_data(j, 1) = ...
             Arr_data(j, 2) = ...
             ...
          end if
      next k
       .Cells(4, 1).Resize(UBound(Arr_data), 6).Value = Arr_data 'выгрузка
       Arr_Mem = Array("сторонний", "аренда (к)") 'изменение значения переменной                
далее необходимо заново сформировать и выгрузить массив Arr_data, но для отбора данных использовать новое значение переменной Arr_Mem. Сейчас это организовано повтором кода, но ведь код ПОЛНОСТЬЮ идентичен. Отсюда вопрос, можно ли каким-либо образом использовать этот код повторно. Я додумался только до применения оператора GoTo (сразу после изменения Arr_Mem, ну и метку в соответствующее место выставить), но я многократно видел на форумах негативное отношение к этому оператору и хотелось бы узнать можно ли и как ,решить такой вопрос иначе.
Заранее спасибо всем откликнувшимся
Поиск необходимого значение (города) по 2 и более условиям
 
Доброго времени суток, уважаемые форумчане. Всех с наступившей весной! Вылезла тут проблемка, хотелось бы узнать решаема ли она. Итак: есть таблица 3 на 7 строк, в первом столбце страны, в втором - условие, в третьем столицы. Требуется, используя ИНДЕКС, найти значение в 3 столбце, НО при выполнении условия. Формулой или кодом неважно (при наличии формулы в код я надеюсь и сам смогу обратить). Без учета условия формула более чем понятная  =ИНДЕКС(A1:C7;ПОИСКПОЗ(F1;A1:A7;0);3). А вот можно ли дополнительно выставить условие я не знаю
P.S.Заранее спасибо всем откликнувшимся
Макрос создания дополнительного меню для перехода по листам
 
Доброго времени суток, уважаемые форумчане. Натолкнулся на нашем форуме на вопрос: https://www.planetaexcel.ru/forum/index.php?PAGE_NAME=read&FID=1&TID=137602&... и попробовал переделать под свои нужды, а именно создание доп. меню для перехода между листами. Получилось следующее:
Код
Sub MakeMenu() 'Добавление пунктов контекстного меню
    Dim NewMenu As CommandBarControl, Item As CommandBarControl, ws As Worksheet, MenuCount As Long, i As Long, Arr_ws As String

    For Each ws In Worksheets
        If ws.Visible = True Then Arr_ws = Join(Array(ws.Name, Arr_ws))
    Next ws
    
    ReDim Cap(1 To UBound(Split(Arr_ws)))
    ReDim Mac(1 To UBound(Split(Arr_ws)))
        For i = 1 To UBound(Split(Arr_ws))
            Cap(i) = Split(Arr_ws)(UBound(Split(Arr_ws)) - i)
            Mac(i) = "Sw_Sh" & i
        Next i

    On Error Resume Next
    Application.CommandBars("Cell").Controls("&Переход на лист").Delete 'Удалить меню, если оно уже существует
    On Error GoTo 0
    
'   Добавление меню
    MenuCount = Application.CommandBars("Cell").Controls.Count
    Set NewMenu = Application.CommandBars("Cell").Controls.Add(Type:=msoControlPopup, Before:=MenuCount, temporary:=True)
    NewMenu.Caption = "&Переход на лист"
    
    For i = 1 To UBound(Split(Arr_ws)) 'Добавление пунктов меню
        Set Item = NewMenu.Controls.Add(Type:=msocontrolbutton, temporary:=True)
        Item.Caption = Cap(i)
        Item.OnAction = Mac(i)
   Next i
End Sub

Sub DeleteMenu() 'Удаление меню перед закрытием
    On Error Resume Next
    Application.CommandBars(1).Controls("Переход на лист").Delete
End Sub 

ну и соответственно макросы перехода на лист:

Код
Sub Sw_Sh1()
   Sheets(1).Activate
End Sub

Sub Sw_Sh2()
   Sheets(2).Activate
End Sub
...
В принципе все работает, но хочется сделать более универсальнее. Ведь если этот код вставить в рабочий файл, где номера листов уже не идут в строгом порядке, придется тщательно проверять соответствие имени и индекса листа. А задумывалось следующее: либо сразу делать соответствие пункта меню и команды на переход, вроде
Код
Cap(i) = Split(Arr_ws)(UBound(Split(Arr_ws)) - i)
Mac(i) = Sheets(Split(Arr_ws)(UBound(Split(Arr_ws)) - i)).Activate
Либо пытаться передать в  переменную (например wh) имя выбранного листа и далее в одном универсальном макросе:
Код
Sub Univ()   
     Sheets(wk).Activate
End Sub
но не смог разобраться в каком месте кода переменой следует присваивать значение . Можно ли сделать так? (или иначе, самое главное результат).
P.S. Заранее спасибо всем откликнувшимся
Перестала работать отправка почты через CDO, отказ SMPT сервера
 
Доброго времени суток, уважаемые форумчане. В некоторых своих файлах использовал метод отправки почты без использования сторонних программ через CDO, взятый отсюда:https://www.excel-vba.ru/chto-umeet-excel/kak-otpravit-pismo-iz-excel/. До последнего времени все было ОК, но вот уже несколько дней код (нетронутый) письмо не отправляет и показывает ошибку -2147220975: sMsg = "Отказ сервера SMTP". Повторюсь, код не трогал, настройки, пароли не менял, при пошаговой проверке все значения переменных корректны, до строки:
Код
.Send
все ОК, ставлю не ней стоп, в Watches значение Err.Number =0. Прохожу следующий шаг и  :cry: Err.Number = -2147220975. Письма на своей почте не вижу. Что могло случиться? Код за исключением своего адреса и пароля и разумеется проверочного ящика не трогал, проверил еще раз сегодня. Если не трудно, не мог бы кто-нибудь проверить?
2 колонки в Combobox при создании через ActiveSheet.OLEObjects.Add
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, можно ли решить данный вопрос. Итак, по условиям создаю на листе Combobox  и заполняю его значениями:
Код
    Set objOle = ActiveSheet.OLEObjects.Add(ClassType:="Forms.ComboBox.1", Left:=ActiveCell.Left, Top:=ActiveCell.Top, Width:=200, Height:=30)
    Set cboCombo = objOle.Object
    cboCombo.BackColor = 255
    
        For i = 1 To 5
            cboCombo.AddItem i
        Next i
Все работает, но можно ли сделать этот Combobox 2 колоночным и  и заполнить его, ведь свойство ColumnCount  у него есть (cboCombo.ColumnCount = 2). И, если можно то как?
Заранее спасибо всем откликнувшимся.
Значение переменной по умолчанию
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, как можно решить возникший у меня вопрос. Итак: для отбора данных внутри цикла использую конструкцию:
Код
...
If IsNumeric(Application.Match(x(i, 1), Arr_opt, 0)) Then
...
массив Arr_opt формирую, разумеется до этого:
Код
If Len(Me.Opt_help.Value) > 0 Then
      Arr_opt = Array("замена", "металлолом", "хоз. нужды")
Else: Arr_opt = Array("")
End If
Если комбобокс (Me.Opt_help.Value) заполнен, то Arr_opt заполняется корректно и правильно отбирает данные, но при пустом комбобоксе проверке должно удовлетворять ЛЮБОЕ значение x(i, 1). Я пробовал указывать и Arr_opt = Array("*") и Arr_opt = Array(""), но нет, проверка не проходит (ведь какое-либо значение в x(i, 1) есть обязательно. Как можно решить данный вопрос и указать, что для отбор подходит любое значение?
Заранее спасибо всем откликнувшимся.
Функция обратной сортировки массива
 
Доброго времени суток, уважаемые форумчане. В работе регулярно использую найденную на просторах сети функцию сортировки массива:
Код
Function Sort_Array(ByRef x(), n As Long) 'функция сортировки массивов
    Dim st As Long, d As Long, f As Long, u As Long, v As Variant
        If IsArray(x) Then
            f = LBound(x): d = f
            For u = f + 1 To UBound(x)
                If x(u, n) < x(d, n) Then
                    For st = 1 To UBound(x, 2)
                        v = x(d, st): x(d, st) = x(u, st): x(u, st) = v
                    Next st
                        u = d - 1: d = u - 1: If u < f Then d = u: u = f
                End If
                    d = d + 1
            Next u
        End If
End Function
все работает нормально, достаточно в коде указать номер столбца по которому производится сортировка (Sort_Array Arr, 2 ) и все ОК. Но сейчас мне потребовалась отсортировать массив в обратном порядке, чтобы даты (во 2 столбце) располагались по убыванию. И вот никак не могу понять что надо изменить в коде (помимо имени функции) чтобы так было?
Заранее спасибо всем откликнувшимся.
Использование свойства AfterUpdate, Прошу объяснить поведение Excel
 
Доброго времени суток, уважаемые форумчане. Пол-дня сегодня потерял, пытаясь разобраться. Итак, на форме есть текстбокс и придумалось мне, чтобы код по вставке данных срабатывал на нажатие Enter после ввода числа в упомянутый текстбокс (подобрал перебором, change или select не подходят, т.к. число может быть из нескольких разрядов). Код вышел таким (Write_mat это имя текстбокса, формы вызывается двойным кликом в столбце G):
Код
Private Sub Write_mat_AfterUpdate() 'аналог кнопки (сработка по Enter)
    Dim LastRow_r As Long
        On Error Resume Next
        If Len(Me.Consumer.Value) > 0 Then
            If CDbl(Me.Write_mat.Value) <= CDbl(Me.Rest.Value) Then
                With Sheets("Расход")
                    LastRow_r = .Cells(Rows.Count, 2).End(xlUp).Row + 1
                    .Cells(LastRow_r, 1).Value = ActiveCell.Offset(, -5).Value 'дата расхода
 ...
                End With
                    Unload Me
            Else: MsgBox "Вы не можете списать более " & Me.Rest.Value & ActiveCell.Offset(, -1).Value, vbCritical, "Внимание! Превышение остатка": Exit Sub
            End If
            If CDbl(Me.Write_mat.Value) = CDbl(Me.Rest.Value) Then ActiveCell.Interior.Color = &HFF00& 'визуализация полного расхода позиции
        Else
            Me.Consumer.BackColor = &HFF&
            MsgBox "Вы не указали потребителя (поле выделено красным цветом), исправьте", vbInformation, "Внимание!": Exit Sub
    End If
End Sub
но когда начал тестировать, то excel всякий раз выпадал с ошибкой: automation error. Вызванный объект был отключен от клиентов. Пробовал отключать все что можно и в коде инициализации формы и в приведенном выше коде и в коде листов - ничего не помогает. Уже от отчаяния попробовал перенести код с события  AfterUpdate просто на кнопку и все заработало, так что решение так или иначе есть, но вопросы все-таки остались: почему такое поведение события AfterUpdate  и можно ли все таки сделать так ,чтобы код срабатывал на нажатие на клавиатуре кнопки Enter?
Заранее спасибо всем откликнувшимся.
Страницы: 1 2 3 4 5 6 След.
Наверх