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

Страницы: 1
Совместимость .XLSB в разных версиях Excel?
 
Случилось странное. На работе начал писать макрос в Excel 2007. Вечером забрал xlsb-файл домой, поработал с ним в Excel 2021, и отправил себе обратно на рабочую почту. Утром, на работе, обнаружил что файл пришел битый, не открывается (обнаружено ... содержимое... восстановить? после восстановления - полностью поломанный файл - не хватает главного листа, куча каких-то левых листов, полностью слетевшее форматирование и т.п.). Грешил на майл.ру, но не поленился - сгонял домой, и привез файл на флешке. То же самое.
На соседней машине поднял офис 2021, убедился что файл там открывается нормально, пересохранил в .xlsm, перенес на рабочий комп - и всё норм, работает в 2007.
Вопрос!!! Чем xlsb в 2021 офисе отличается от xlsb в 2007? Или что ещё могло стать причиной такого глюка?
Изменено: Alexcx - 24.04.2025 15:38:58
условное форматирование таблицы из VBA, Глюк Excel?
 
Цитата
написал:
Вы делаете это макросом - то не обращаете внимания, какая ячейка активная. А УФ - обращает. Вот и получается такой казус.
Мда, интересный материал для размышления)) Много лет работаю с VBA, и всегда считал методы select и activate пережитками макро-рекордера. Придется пересмотреть этот момент. Ещё раз спасибо за подсказку.
условное форматирование таблицы из VBA, Глюк Excel?
 
Дмитрий(The_Prist) Щербаков, точно, помогло, спасибо.

Но смысл косяка остался где-то за границей понимания. Видимо придется просто запомнить.
условное форматирование таблицы из VBA, Глюк Excel?
 
Приветствую, господа.
Столкнулся с непонятным поведением excel, надеюсь кто-то окажется внимательнее и поймет что происходит.

Итак. Есть макрос, выполняющий определенные вычисления в таблице. На основании полученных итогов таблица должна быть раскрашена.
Чтобы точнее прицелится, ввожу в Immediate команду:
Код
? ActiveSheet.ListObjects("реестр").DataBodyRange.Cells(1,16).Address(0, 1)
$P6
пока всё правильно, мне действительно  нужно создать правило на основании клетки P6
Дописываю в конце макроса такой код:
Код
With ActiveSheet.ListObjects("реестр").DataBodyRange
 .FormatConditions.Delete
 .FormatConditions.Add Type:=xlExpression, Formula1:="=" & .Cells(1, 16).Address(0, 1) & ">0"
 .FormatConditions(1).Interior.Color = vbGreen
End With
Выполняю макрос, замечаю что клетки раскрасились как-то неправильно, и обнаруживаю, что в созданном правиле прописалась формула "=$P8>0"

Вручную исправляю эту формулу, вся таблица раскрашивается как надо.
Внимание, вопрос! В какой момент выражение, вычисляющееся в "$P6" вдруг выдало "$P8" ????
Изменено: Alexcx - 21.02.2025 09:05:45
range в массив, туплю
 
Цитата
написал:
dim arr
arr = [A1].resize(5).value
но на выхлопе получается двумерный массив (5,1)
Отвечу сам себе, т.к. решение найдено.

Всего лишь:
Код
arr = Application.Transpose([A1].resize(5).value)
Теперь arr имеет только одну размерность (5). Обращения вида arr(5) ошибок не дают.


И обратно массив сливается одной строчкой:

Код
[A1].Resize(UBound(arr)) = Application.Transpose(arr)
Промежуточные итоги, subtotal
 
Для приложенного примера:
Код
Sub flt()
    ActiveSheet.AutoFilterMode = False
    [B1].Formula = "=SUBTOTAL(9,B3:B" & ActiveSheet.UsedRange.Rows.Count & ")"
    Rows(2).AutoFilter field:=2, Criteria1:=300
    ActiveSheet.AutoFilter.ApplyFilter
End Sub

Ключевое слово ApplyFilter. Получилось?
Поиск текстовых данных по разным столбцам, Нужно найти определенные слова в трех столбцах и в соседнем столбце присвоить, значения, которые за этими словами закреплены
 
Формула для [E2] из примера:
Код
=ЕСЛИ(СЧЁТЕСЛИ(B2:D2;I2)=1;J2;"-")
и копируем вниз.


Или нужно оформить макрос?
range в массив, туплю
 
Цитата
написал:
Свойство  Range.Value  так устроено - возвращает одно скалярное значение (для ячейки) или двумерный массив (для диапазонов, состоящих более, чем из одной ячейки).
Принял к сведению, спасибо. Будут лишние запятые в макросах, ну и пусть.
range в массив, туплю
 
Цитата
написал:
двумерного массива в одномерный
Это запросто, но мой вопрос относился к встроенным возможностям Excel/VBA. Может есть какие-то тонкости синтаксиса?
range в массив, туплю
 
Цитата
написал:
чем Вам второе измерение не нравится?
Потому что регулярно натыкаюсь на ошибки "subscript out of range" в собственном коде ) потому и говорю - не путаю ли я VBA с другими языками. Вроде ведь логично: одномерный диапазон присваивается массиву. Но массив почему-то получается двумерный (x to 1), причем вторая размерность всегда 1.
Изменено: Alexcx - 18.11.2024 17:10:20
range в массив, туплю
 
Цитата
написал:
Ячейка имеет 2 измерения
В  смысле .row и .column? так это свойства (properties) объекта, а не измерения (dimensions). Для получения адреса клетки это актуально, но если нужно получить массив значений из одной строки? столбца?
range в массив, туплю
 
Коллеги, прошу подсказку. я то ли туплю, то ли путаю VBA с другим языком.
Задача: загнать range в массив.
Вроде бы тривиально:
dim arr
arr = [A1].resize(5).value
но на выхлопе получается двумерный массив (5,1),  то есть обращение типа msgbox(arr(3)) даст ошибку "subscript out of range", а нужно писать msgbox(arr(3,1)).
А можно ли одним оператором создать из одномерного range одномерный массив? Или для этого придется обходить заданный range циклом?
Изменено: Alexcx - 18.11.2024 16:30:06
суммирование макросом, нужен быстрый алгоритм
 
Цитата
написал:
У меня всё работаетКодSub t()
Dim dic As New Dictionary
   dic.add "test", Array(10, 20, 30)
   Debug.Print dic.Item("test")(1) ' 10 (for Option Base 1)
End Sub

Да, так работает.
А  не получается вот так:
Код
dic.Item("test")(1) = dic.Item("test")(1) + 100 'элемент массива почему-то не изменяется.

Приходится делать через промежуточный массив:
Код
arr = dic.Item("test"): arr(1) = arr(1) + 100: dic.Item("test") = arr ' а вот так работает
А нельзя ли напрямую?
суммирование макросом, нужен быстрый алгоритм
 
Это мощно. Переписал свой макрос со словарем. Мало того что он работать стал на порядок быстрее, так ещё и код в три раза компактнее получился:
Код
Dim dic1: Set dic1 = CreateObject("Scripting.Dictionary")

With Sheets("Лист1")
    For i = 2 To .UsedRange.Rows.Count
        key1 = Left(CStr(.Cells(i, 3)), 10) & CStr(.Cells(i, 2))
        If Not dic1.exists(key1) Then dic1.Add key1, 0
        dic1.Item(key1) = dic1.Item(key1) + CDbl(.Cells(i, 4))
     Next
End With

Application.ScreenUpdating = False
With Sheets("Лист2")
    For i = 3 To .UsedRange.Rows.Count
        key1 = Left(CStr(.Cells(i, 1)), 10) & CStr(.Cells(i, 2))
        If dic1.exists(key1) Then .Cells(i, 3).Value = dic1.Item(key1)
     Next
End With
Application.ScreenUpdating = True


Может и не идеально, но скорость меня уже устраивает. То что раньше работало до 10 минут, выполняется в пределах 3-5 секунд. Ура.

Благодарю за подсказку sokol92, БМВ, Jack Famous,

А не подскажете ли ещё, если в словарь добавить массив, как адресоваться к его элементам? У меня не получилось.

Например:
dic1.Add key1, array(10, 20, 30)
msgbox Dic1.Item(key1)(1)
Результат - 0.
Изменено: Alexcx - 29.05.2024 12:43:51
суммирование макросом, нужен быстрый алгоритм
 
Привет, коллеги. Прошу помочь с алгоритмом, теоретической подготовки не хватает.

Суть в следующем. Есть книга с двумя (на самом деле гораздо больше) листами. На одном из них (назовем его Лист1)  несколько десятков или даже сотен тысяч записей, которые постоянно обновляются и пополняются копированием-вставкой из внешнего источника. Данные на этом листе не упорядочены, и содержат графы  "дата", "ID",  некая "сумма", и много всего прочего. На другом листе (Лист2) нужно макросом сформировать типа сводного отчета, в котором  данные первого листа подсуммируются по "дате" + "ID".
Есть рабочее решение, но оно слишком медленно, поэтому и прошу подсказки. Суть моего макроса состоит в том, что содержимое обоих листов считывается в два массива, потом двумя вложенными FOR даные суммируются  (внешний for пробегает больший массив1, а внутренний накапливает в меньшем массиве2 суммы по заданным условиям), затем меньший массив заливается обратно на Лист2 конструкцией типа cells(...).resize(...).value = arr. Этот макрос работает несколько минут, что очень долго, учитывая прочие условия задачи.
Со сводными таблицами знаком, в данном случае это неприменимо, потому что Лист2 имеет фиксированную разметку  - это  достаточно сложный  отчет, который нужно заполнить цифрами по одной  кнопке, нажатой пользователем.

С функцией СУММЕСЛИМН тоже знаком, но если её использовать на этом объеме данных, перерасчет всей книги на шести ядрах core i5-8500 c 16GB памяти занимает почти 2 минуты, что также недопустимо, т.к. перерасчет будет запускаться на каждое редактирование, фильтрацию и т.п. (application.calculation =xlcalculationmanual не предлагать, противоречит прочим неозвученным условиям)

В общем, требуется именно макрос, который будет работать по кнопке, и по возможности "мгновенно".
Накидайте пожалуйста идей или ссылок на описание, какой алгоритм суммирования по нескольким условиям самый быстрый. С реализацией в VBA буду разбираться сам. Спасибо.
Изменено: Alexcx - 27.05.2024 19:29:07
Страницы: 1
Наверх