eugenefoxx
Участник

Offline
Сообщений: 22
|
Здравствуйте! Подскажите, как переписать по Libreoffice Basic следующий код - Как видно, берутся данные с одной страницы по ключевому столбцу и проводиться поиск соответствующих значений по нему на другой странице.
ThisWorkbook.Worksheets("Сводный анализ").Activate With ThisWorkbook.Sheets("Сводный анализ") 'используется кодовое имя iLastrow = .Cells(Rows.Count, 5).End(xlUp).Row a = Range(.[e3], .Range("E" & iLastrow)).Value End With With ThisWorkbook.Sheets("Лист1") 'используется кодовое имя iLastrow = .Cells(Rows.Count, 2).End(xlUp).Row b = Range(.[j6], .Range("B" & iLastrow)).Value End With ReDim c(1 To UBound(a), 1 To 7) With CreateObject("Scripting.Dictionary") For i = 1 To UBound(b) .Item(b(i, 1)) = i Next For i = 1 To UBound(a) If .exists(a(i, 1)) Then c(i, 1) = b(.Item(a(i, 1)), 5) c(i, 3) = b(.Item(a(i, 1)), 6) c(i, 4) = b(.Item(a(i, 1)), 8) c(i, 5) = b(.Item(a(i, 1)), 4) End If Next End With
With ThisWorkbook.Sheets("Сводный анализ") 'используется кодовое имя .[f3].Resize(UBound(c), 5) = c .Activate End With
|
|
« Последнее редактирование: 30 Сентябрь 2018, 11:06 от eugenefoxx »
|
Записан
|
|
|
|
economist
|
Ну, во-первых, этот (да и другой) код в LO61 должен работать и так (почти). Попробуйте вставить код с LO 6.1 Calc и выполните пошагово, по F8: option vbasupport 1
sub test() ThisWorkbook.Worksheets("Сводный анализ").Activate With ThisWorkbook.Sheets("Сводный анализ") 'используется кодовое имя iLastrow = .Cells(Rows.Count, 5).End(xlUp).Row a = Range(.[e3], .Range("E" & iLastrow)).Value End With With ThisWorkbook.Sheets("Лист1") 'используется кодовое имя iLastrow = .Cells(Rows.Count, 2).End(xlUp).Row b = Range(.[j6], .Range("B" & iLastrow)).Value End With ReDim c(1 To UBound(a), 1 To 7) With CreateObject("Scripting.Dictionary") For i = 1 To UBound(b) .Item(b(i, 1)) = i Next For i = 1 To UBound(a) If .exists(a(i, 1)) Then c(i, 1) = b(.Item(a(i, 1)), 5) c(i, 3) = b(.Item(a(i, 1)), 6) c(i, 4) = b(.Item(a(i, 1)), 8) c(i, 5) = b(.Item(a(i, 1)), 4) End If Next End With
With ThisWorkbook.Sheets("Сводный анализ") 'используется кодовое имя .[f3].Resize(UBound(c), 5) = c .Activate End With end sub
Огромные усилия людей по имплементации VBA в LO направлены на то, чтобы программирование электронных таблиц было безграничным и использована огромная кодовая база примеров на VBA, доставшаяся (да чего уж там, пополняющаяся стократно быстрее каждый день) от Microsoft Excel, самого популярного прикладного приложения в мире. Усилия по самостоятельной доработке имеющихся VBA макросов в Calc окупятся сторицей, вы освоите еще один волшебный инструмент. И в связи с этим есть ещё во-вторых и в-третьих: Во-вторых, макрос написан излишне многословно. В частности, все блоки With - избыточны, все кроме последнего - заменяются формулами Calс (а формулы в эл. таблицах - это главное, что их отличает от разлинованного блокнота, их-то точно нужно изучить). В-третьих, для таких простых задач (поиск значения в строке другой таблице и возврату значения нужного столбца в эту) - вовсе не нужны макросы, достаточно освоить часто нужную функцию =ВПР(=VLOOKUP) или связку функций =ИНДЕКС(ПОИСКПОЗ...) или INDEX/MATCH.
|
|
|
Записан
|
Руб. за сто, что Питоньяк Любит водку и коньяк! Потому что мне, без оных, - Не понять его никак...
|
|
|
eugenefoxx
Участник

Offline
Сообщений: 22
|
Пробую запустить в текущем варианте, это приводит к BASIC runtime error. '91' Objectiv variable not set или BASIC runtime error. '12'. ThisWorkbook. Эта ошибка проявляется в строке ThisWorkbook.Worksheets("Сводный анализ").Activate. По поводу формул. Я их также активно использую, но при создании макроса по обработке нескольких файлов с многотысячными строками, формулы занимают много времени. Поэтому решил в таких ситуациях использовать массивы.
|
|
« Последнее редактирование: 30 Сентябрь 2018, 19:16 от eugenefoxx »
|
Записан
|
|
|
|
economist
|
eugenefoxx - пробуете запустить где (ОС, версия LO, приложение Calc?) "Текущий вариант" - это что: ваш, мой код?
Вот как я пробовал (вложение). Работает в LO 5.4-6.1
Готовые формулы в 99% реальных задач не могут считать медленнее чем макрос.
|
|
« Последнее редактирование: 30 Сентябрь 2018, 19:45 от economist »
|
Записан
|
Руб. за сто, что Питоньяк Любит водку и коньяк! Потому что мне, без оных, - Не понять его никак...
|
|
|
eugenefoxx
Участник

Offline
Сообщений: 22
|
"Текущий вариант" - это ОС - Archlinux, LO 6.1, Calc Запускаю код из внешнего файла. В начале прописан код на чистом LO Basic (обработка внешних файлов и загрузка их в основной сводный внешний файл (шаблон)), далее я пытаюсь запустить это самый код на VBA, и возникает ошибка на ThisWorkbook.Worksheets("Сводный анализ").Activate. В Вашем примере у меня также код работает.
|
|
« Последнее редактирование: 30 Сентябрь 2018, 20:16 от eugenefoxx »
|
Записан
|
|
|
|
economist
|
В Вашем примере у меня также код работает. Если мой код в моем файле работает - добавьте в свой "внешний файл" (полагаю это ODS-файл) - первую строку из кода в посте #1 и надо переоткрыть файл. Также стоит проверить в Настройки - Свойства VBA - поставить все галки и переоткрыть файл. Метод Activate - это из VBA, не исключено что под Арчем что-то из LO выпилено.
|
|
|
Записан
|
Руб. за сто, что Питоньяк Любит водку и коньяк! Потому что мне, без оных, - Не понять его никак...
|
|
|
eugenefoxx
Участник

Offline
Сообщений: 22
|
Переделал на запуск кода в текущей книге (.ods). Возникла другая проблема. Теперь на строчке .Item(b(i, 1)) = i . Ошибка BASIC runtime error. '323'. Module cannot be loaded; invalid format. Возможно это связано с With CreateObject("Scripting.Dictionary"). Я думаю это приговор.
|
|
« Последнее редактирование: 30 Сентябрь 2018, 21:14 от eugenefoxx »
|
Записан
|
|
|
|
economist
|
Эта строка
With CreateObject("Scripting.Dictionary")
вообще не нужна. Удалите её и закрывающий End with. Строку с ошибкой легко вычислить отладкой по F8. Вы бы описали словами что должен делать макрос.
|
|
« Последнее редактирование: 1 Октябрь 2018, 00:32 от economist »
|
Записан
|
Руб. за сто, что Питоньяк Любит водку и коньяк! Потому что мне, без оных, - Не понять его никак...
|
|
|
Bigor
|
Вы бы описали словами что должен делать макрос. И файлик приложили
|
|
|
Записан
|
|
|
|
eugenefoxx
Участник

Offline
Сообщений: 22
|
Почему я сказал, что это приговор, потому что Dictionary Object - Description Object that stores data key, item pairs и у него есть свойство Item. По всей видимости vbasupport такой объект не поддерживает. И поиск свойства item не будет работать вне цикла объекта Dictionary, т.к. это, как выяснили, его свойство.
|
|
|
Записан
|
|
|
|
Bigor
|
так напишите чего надо сделать, может можно это и без Dictionary Object - Description Object that stores data key, item pairs сделать
|
|
|
Записан
|
|
|
|
mikekaganski
|
Интересное кино... Как всем известно, Dictionary Object - это COM-объект, предоставляемый MS Script Runtime, являющегося компонентом Windows. Я полез искать документацию, подтверждающую этот простой факт (чтобы пояснить, что это нормально, когда ОС-специфичные вещи отказываются работать на других платформах). И был удивлён, что во время недавнего преобразования документации на сайте Microsoft статьи по Script Runtime волшебным образом перекочевали в объекты VBA. Конечно, можно найти и архивную копию (которая, внезапно, является более полной)... но вот я теперь думаю: это что, такой тонкий способ расширить определение VBA до "всё на свере, что есть в Windows", чтобы сделать реализацию этого невозможной третьей стороной? (Интересно, а под macOS как это работает в MS Office?)
|
|
|
Записан
|
|
|
|
economist
|
eugenefoxx - повода для грусти нет. Любой "словарь" можно заменить двумерным массивом N*2. Да и других вариантов масса. Может стоит задуматься и выбрать что-то еще?
Если я сталкиваюсь с 20k+ строками (а это предел "комфорта" и в Excel. и в Calc), - то сразу иду либо в СУБД (SQLite) или в Python с его сверхбыстрыми list, tuple, dictionary, написанных на языке С, с кучей методов поиска, сортировки, реверсного поиска итп. Также не стоит сбрасывать со счетов старый добрый CSV/TSV-формат, который читается и парсится на LOBasic и VBA почти одинаково быстро и уступает СУБД/Python считанные "разы" в скорости.
|
|
|
Записан
|
Руб. за сто, что Питоньяк Любит водку и коньяк! Потому что мне, без оных, - Не понять его никак...
|
|
|
eugenefoxx
Участник

Offline
Сообщений: 22
|
economist - спасибо за советы. Я это понимаю. Буду пробовать, т.к. не сильно упражняюсь в таких "занятиях". Хотелось на LOBasic, но пока еще решаю эту проблему для себя. В целом задача простая. Как видно на примере VBA, на одной странице выбирается ключевой столбец с данными, считывается до конца строки, потом по нему в другом массиве, на другой странице, проводиться поиск необходимых значений, соответственно по такому же ключу. Т.е. тут сравниваются две базы данных, которые должны соответствовать другу другу. Не знаю, нужен ли для этого пример файла с данными. Тут можно все что угодно представить. Если будет хоть какое-то решение, буду благодарен. Допилю сам, лишь бы сдвинуться с мертвой точки. Как уже говорил, формулы я применяю, но тут по сути нужен скрипт для автоматической обработки, тем более массив информации большой.
|
|
« Последнее редактирование: 1 Октябрь 2018, 21:24 от eugenefoxx »
|
Записан
|
|
|
|
economist
|
Скрипт/макрос, даже если массив огромен, может быть тут "однострочный", просто вставляющий готовую нужную формулу. Это выглядит примерно так:
[B1:B10000].FormulaLocal="=ВПР(ЧТО;ГДЕ;СТОЛБЕЦ;ЛОЖЬ)"
И будет то, что нужно - браться по ключу данные из другой таблицы и подставляться в имеющуюся. Именованные диапазоны ЧТО ГДЕ - тоже можно задать макросом, или указать явно, например так [A2:A10000]
Макросы имеют один "побочный эффект" - они часто провоцируют "поток программирования" там, где это вовсе не нужно. Массивы, словари, циклы, сплошные области данных - это всё в данной задаче и VBA-коде - избыточно.
Формулой данная задача (построчное сравнение двух "перемешанных" таблиц) - решается примерно за минуту, именно столько на неё тратят мои коллеги, "не умеющие" макросы, но умеющие =ВПР().
|
|
|
Записан
|
Руб. за сто, что Питоньяк Любит водку и коньяк! Потому что мне, без оных, - Не понять его никак...
|
|
|
|