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

Страницы: 1 2 3 4 5 След.
Работа с отфильтрованным словарем
 
Доброго времени суток, уважаемые форумчане. Возник небольшой вопроси, если на него есть решение, то буду очень рад его увидеть. Итак, наполняется словарь: в ключах названия, в итемах количество:    
Код
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?
Заранее спасибо всем откликнувшимся.
Формирование массива с неизвестным заранее кол-вом столбцов
 
Доброго времени суток, уважаемые форумчане. Никак не могу решить возникшую задачу 8-0, помогите пожалуйста. Итак, на листе имеются данные по результатам подразделений (диапазон A3:D38). Необходимо сформировать массив так, чтобы конечный результат выглядел как диапазон H9:J21 (тот что сейчас сформирован вручную и выделен зеленым). Теперь главная  особенность условия: я не знаю заранее сколько столбцов будет в массиве (сейчас для 1 года это 2 столбца, в следующим году 3 и т.д.). При этом рассчитать это количество я смогу без труда, откуда начинать счет и на какой строке заканчивать (в реальном коде) я тоже знаю как рассчитать. Результат должен быть такой же как при нажатии кнопки на листе.
Заранее спасибо всем откликнувшимся
Импорт пользовательских форм и кодов VBA из файла в файл
 
Доброго времени суток, уважаемые форумчане. Заранее приношу извинения за некоторую многобуквенность. Скажу сразу, все нижеизложенное я ЗАДУМАЛ сделать чисто для облегчения своей работы, без полной уверенности в реальности выполнения задачи. Итак, периодически выявляются ошибки или недочеты в кодах созданных мною  (очень часто с помощью нашего форума) файлов или например новые элементы просят сделать на форме. После устранения или доделок приходится по удаленному доступу связываться с пользователями  и, скопировав их файл к себе (или мой обновленный к ним), заменять userform в их файле и/или код на страннице. А задумал я следующее: создается файл, в который помещаются все измененные userform и/или листы, разумеется под теми же именами. На открытие файла вешается приблизительно такой алгоритм:
1. Запрашивается файл для изменений:
Код
           If MsgBox("Вы уверены?", vbCritical + vbYesNo, "Внимание! Подумайте перед ответом") = vbYes Then
                FileName = GetFileName("Укажите файл для импорта", ThisWorkbook.Path) 'запрашиваем имя файла
                If Len(FileName) = 0 Then Exit Sub 'выход, если пользователь отказался от выбора файла
            Else: Exit Sub
            End If
2. Запускаем цикл (и вот здесь мои познания пока кончаются :oops: ): проходим по всем имеющимся userform нового файла и в случае нахождения такого же имени в файле пользователя, сначала удаляем форму (как я понял заменить одинаково называющиеся userform Excel не даст) и КОПИРУЕМ эту userform в файл пользователя, если же формы с таким именем нет в файле пользователя, то просто копируем соответствующую форму.

3. Аналогично проходим по именами листов: если такой лист есть, то меняем КОД (весь целиком) имеющийся на нем на код с такого же листа нового файла, если нет, то просто копируем лист (с кодом и возможными данными) в файл пользователя.

4.После отработки кода файл закрывается и вуаля: у пользователя оказывается файл с обновленными userform и кодами на листах

Можно ли так сделать и как, если можно? Заранее спасибо всем откликнувшимся
Удаление (очистка) вложения при использовании CDO
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, как решить данный вопрос. Вопрос вылез в конкретном примере (о сем ниже), но думаю что он более универсален. Итак, для отправки писем из Excel использую CDO, все работает правильно, но хотелось бы уточнить 1 деталь.
Код
Dim oCDOCnf As Object, oCDOMsg As Object
...
   Set oCDOMsg = CreateObject("CDO.Message")
...
       oCDOMsg.AddAttachment ThisWorkbook.Path & "\" & sFiles
3-я строка кода по ходу цикла добавляет файлы к аттачу письма (повторюсь все работает). Но вот далее по ходу цикла следующие отобранные файлы добавляются к уже имеющимся в аттаче и, естественно, в письме оказываются "лишние" файлы, предназначенные не тому получателю (при рассылке у 1-го получателя имеются только "его" файлы, а у 2-го и "его" и "чужые". Так-то понятно, что надо очистить Attachment, но как можно узнать метод, ведь после точки не показывается подсказка  8-0 . Одним словом как в подобной ситуации узнать синтаксис объекта, если после точки не показываются подсказки?
Заранее спасибо всем откликнувшимся.
Подсчет указанных элементов массива без использования цикла
 
Доброго времени суток, уважаемые форумчане. Подскажите, что сейчас не так в моем коде. Ситуация такая: имеется готовый одномерный массив Arr_Count с данными, необходимо подсчитать сколько раз в массиве встречается тот или иной элемент (в примере буква с). Делать я это пытаюсь с помощью Application.CountIf, но почему-то не получается, код ругается на несовпадение типов 8-0 . Что сейчас написано неверно и как это исправить?
Код
Dim Arr_Count(4)
        Arr_Count(0) = "a"
        Arr_Count(1) = "b"
        Arr_Count(2) = "c"
        Arr_Count(3) = "c"
        Arr_Count(4) = "d"
    MsgBox Application.CountIf([Arr_Count], "c")
Заранее спасибо всем откликнувшимся.
Незапланированная печать листа
 
Доброго времени суток ,уважаемые форумчане, всех  с прошедшим праздником. Ситуация такая: требуется распечатать 2 бланка на 1 листе. делаю я это самым простым способом: копирую строки, вставляю, далее печать листа и удаление вставленных строк. Код
Код
Private Sub Workbook_BeforePrint(Cancel As Boolean) 'предпечатная подготовка листа "Формы"
'    Dim b As Boolean
    With ActiveSheet
'        If b = False Then
        If .Name = "Форма" Then 'обязательно условие: указание имени листа, иначе VBA пытается выполнить код на др. листах
            Application.EnableEvents = False
            .Rows("1:30").Copy .Range("A33")
            .Rows("31:32").RowHeight = 6.75
            .Range("A31:G31").Borders(xlEdgeBottom).LineStyle = xlDashDot
            .Range("$A$1:$G$62").PrintOut Copies:=1
            .Rows("31:62").Delete
'            b = True
            Application.EnableEvents = True
'        End If
        End If
    End With
End Sub
Все в принципе ОК, но по какой-то причине, после распечатки листа (с 2 копиями) Excel выдает команду на печать еще раз и на печать выходит лист с изначальными данными, т.е. с 1 копией. И флаг пытался применять, и отслеживание событий отключал - ничего не помогает 8-0. Четко видно при пошаговой проверке, что выполнение доходит до End Sub и далее (без каких то ошибок или чего иного) вновь идет команда на печать. Почему так происходит и как это победить?
Заранее спасибо всем откликнувшимся.
Поломка после копирования данных: задвоение листов в редакторе VBA.
 
Доброго времени суток, уважаемые форумчане.

Долго пытался сам решить возникшую проблему, но все-таки не смог .

Итак, в незаполненный файл (в котором есть и формы пользователя и макросы и чуть-чуть формул) переношу данные из старого файла, переношу копированием только данных через спец-вставку, все ОК, файл сохраняю, проверяю открытием и вижу сообщение о повреждении файла с предложением восстановить файл. При согласии с предложением файл восстанавливался, но при этом все листы в Microsoft Excel Objects оказывались задвоенными, при этом "копии" имели другой ярлык (такой как на объекта "Эта книга"), при этом код с "основных" листов бесследно исчезал, как и форматирование ячеек (ширина и высота становились стандартными). Проверив все описанное несколько раз с одинаковым результатом я стал копировать данные по 1 листу, каждый раз после этого проверяя на открытие и как казалось нашел "проблемный" лист, при копировании которого начиналась проблема.
Ладно, лист удалил, создал заново чистый, перенес на него только форматирование ячеек, заполнил текст, вставил код на кнопку и пр. и до кучи пересохранился как .xlsb.
Проверил на открытие, все нормально, проверяю на работу макросов, нахожу и исправляю пару ошибок, сохраняю и ...  при открытии вновь вижу сообщение о повреждении, но немного не такое. Во первых файл восстановился нормально, без задвоения листов, во вторых после восстановления было сообщение: Восстановленные записи: Формула из части /xl/worksheets/sheet6.bin

Отсюда наконец мои вопросы по теме:
- что это за мистика с файлом и о каком sheet6 идет речь, если такого листа просто нет (просмотрел тщательно и даже проверил кодом)
- как это исправить, чтобы эта ошибка не проявилась у пользователя?

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

P.S. Приношу извинения за некоторую "многобуквеннность", но этот полтергейст в 2 словах не опишешь.
P.S.2 Файл приложить не могу: исходный открывается нормально, но и то "весит" больше разрешенного на форуме, а уж заполненный даже в .xlsb "весит" более 1,5 Мб, но при этом он ни разу не секретный, так что если надо...
Изменено: OlegO - 21.01.2020 09:39:20
Создание шаблона теста для проверки знаний
 
Доброго времени суток, уважаемые форумчане.

Поручили тут мне составить некий вариант теста для проверки (точнее сказать для тренировки перед проверкой) знаний коллег по фирме. И вот вылез вопрос. Как сделать так, чтобы при выборе варианта вопроса (в прилагаемом примере ячейка А1) в соседних ячейках подгружались бы сам вопрос и варианты ответа на него (данные находятся на соседнем листе), т.е. так как сейчас введено вручную. Кодом или формулой неважно, но кодом было бы полезнее для моих знаний  :)
Подсчет ячеек с определенным комментарием, Можно ли использовать комментарий в ячейке как условие для СУММЕСЛИМН?
 
Доброго времени суток, уважаемые форумчане. Подскажите, пожалуйста, можно ли решить данный вопрос. Итак, имеется диапазон с данными, часть из которых необходимо отобрать и сложить. Делаю я это с помощью СУММЕСЛИМН. В прилагаемом файле формула находится в ячейке F1. Логика отбора такова: в диапазоне условия (А1:А10) ячейка должна быть >0 при этом не совпадать с указанным значением и дополнительно, в другом диапазоне условия (В1:В10) наоборот - совпадать с указанным значением. Все это работает правильно в прилагаемом файле, НО имеется вопрос: как сделать все тоже самое не используя данные диапазона В1:В10, а использовать эти же данные, находящиеся в комментариях ячеек диапазона А1:А10? Доступ к данным комментария можно получить функцией пользователя
Код
Function Get_Text_from_Comment(rCell As Range) 'доступ к информации комментария
    Application.Volatile True
    On Error Resume Next
    Get_Text_from_Comment = rCell.Comment.Text
End Functio
Должны просуммироваться ячейки которые в диапазоне условия имеют значение >0 и указанный комментарий в ячейке. Комментарий будет у ВСЕХ ячеек диапазона.
Можно ли так сделать и как, если можно?
Заранее спасибо всем откликнувшимся
Убрать кавычки, образующиеся при выполнении кода VBA
 
Доброго времени суток, уважаемые форумчане. Заранее прошу прощения за не слишком точное описание проблемы в названии темы, но никак другого не придумалось :oops: . Итак, вопрос: по ходу выполнения макроса, который должен определить УФ, имеется следующая строка (значение i верное):
Код
.FormatConditions.Add Type:=xlCellValue, Operator:=xlNotEqual, Formula1:=Chr(36) & Cells(2, i).Address(False, False)           
УФ должно проверить ячейки на неравенство с указанной ячейкой. В записанном макрорекодером коде эта строка выглядит так:
Код
.FormatConditions.Add Type:=xlCellValue, Operator:=xlNotEqual, Formula1:="=$AE2"

Запись макрорекодера выдает правильный результат: Значение ячейки <> $AE2 А вот мой код, приведенный выше, дает крайне похожий, но немного не такой результат: Значение ячейки <> "$AE2" . УФ, разумеется, отрабатывая такое условие, выдает не тот результат на который я рассчитывал. Что и как нужно написать, чтобы Chr(36) & Cells(2, i).Address(False, False) при правильном значении не имел кавычек в итоговом результате, если конечно дело в кавычках, а не в чем-либо ином. Другими словами как обеспечить для УФ сравнение с содержанием ячейки (в данном случае $AE2, а не с выражением "$AE2"?

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

Страницы: 1 2 3 4 5 След.
Наверх