Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

18 Октябрь 2018, 23:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Доступно и просто о работе в офисных пакетах
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1 2 3 »   Вниз
  Печать  
Автор Тема: Переписать код VBA под Libreoffice Basic по поиску в массиве  (Прочитано 2129 раз)
0 Пользователей и 1 Гость смотрят эту тему.
eugenefoxx
Участник
**
Offline Offline

Сообщений: 17


« Стартовое сообщение: 30 Сентябрь 2018, 10:27 »

Здравствуйте! Подскажите, как переписать по 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
Форумчанин
***
Offline Offline

Сообщений: 927


« Ответ #1: 30 Сентябрь 2018, 11:33 »

Ну, во-первых, этот (да и другой) код в 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 Offline

Сообщений: 17


« Ответ #2: 30 Сентябрь 2018, 14:57 »

Пробую запустить в текущем варианте, это приводит к BASIC runtime error. '91' Objectiv variable not set или BASIC runtime error. '12'. ThisWorkbook. Эта ошибка проявляется в строке ThisWorkbook.Worksheets("Сводный анализ").Activate.
По поводу формул. Я их также активно использую, но при создании макроса по обработке нескольких файлов с многотысячными строками, формулы занимают много времени. Поэтому решил в таких ситуациях использовать массивы.
« Последнее редактирование: 30 Сентябрь 2018, 19:16 от eugenefoxx » Записан
economist
Форумчанин
***
Offline Offline

Сообщений: 927


« Ответ #3: 30 Сентябрь 2018, 19:41 »

eugenefoxx - пробуете запустить где (ОС, версия LO, приложение Calc?)
"Текущий вариант" - это что: ваш, мой код? 

Вот как я пробовал (вложение). Работает в LO 5.4-6.1

Готовые формулы в 99% реальных задач не могут считать медленнее чем макрос.

* VBA макрос.ods (9.23 Кб - загружено 7 раз.)
« Последнее редактирование: 30 Сентябрь 2018, 19:45 от economist » Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
eugenefoxx
Участник
**
Offline Offline

Сообщений: 17


« Ответ #4: 30 Сентябрь 2018, 20:06 »

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

Сообщений: 927


« Ответ #5: 30 Сентябрь 2018, 20:51 »

В Вашем примере у меня также код работает.

Если мой код в моем файле работает - добавьте в свой "внешний файл" (полагаю это ODS-файл) - первую строку из кода в посте #1 и надо переоткрыть файл. Также стоит проверить в Настройки - Свойства VBA - поставить все галки и переоткрыть файл.

Метод Activate - это из VBA, не исключено что под Арчем что-то из LO выпилено.
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
eugenefoxx
Участник
**
Offline Offline

Сообщений: 17


« Ответ #6: 30 Сентябрь 2018, 20:52 »

Переделал на запуск кода в текущей книге (.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
Форумчанин
***
Offline Offline

Сообщений: 927


« Ответ #7: 1 Октябрь 2018, 00:31 »

Эта строка

With CreateObject("Scripting.Dictionary")

вообще не нужна. Удалите её и закрывающий End with.
Строку с ошибкой легко вычислить отладкой по F8.
Вы бы описали словами что должен делать макрос.
« Последнее редактирование: 1 Октябрь 2018, 00:32 от economist » Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
Bigor
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 314


« Ответ #8: 1 Октябрь 2018, 07:09 »

Вы бы описали словами что должен делать макрос.
И файлик приложили
Записан
eugenefoxx
Участник
**
Offline Offline

Сообщений: 17


« Ответ #9: 1 Октябрь 2018, 08:23 »

Почему я сказал, что это приговор, потому что Dictionary Object - Description Object that stores data key, item pairs и у него есть свойство Item. По всей видимости  vbasupport такой объект не поддерживает. И поиск свойства item не будет работать вне цикла объекта Dictionary, т.к. это, как выяснили, его свойство.
Записан
Bigor
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 314


« Ответ #10: 1 Октябрь 2018, 11:16 »

так напишите чего надо сделать, может можно это и без Dictionary Object - Description Object that stores data key, item pairs  сделать
Записан
mikekaganski
Мастер
*****
Online Online

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 063


« Ответ #11: 1 Октябрь 2018, 15:20 »

Интересное кино...

Как всем известно, Dictionary Object - это COM-объект, предоставляемый MS Script Runtime, являющегося компонентом Windows. Я полез искать документацию, подтверждающую этот простой факт (чтобы пояснить, что это нормально, когда ОС-специфичные вещи отказываются работать на других платформах). И был удивлён, что во время недавнего преобразования документации на сайте Microsoft статьи по Script Runtime волшебным образом перекочевали в объекты VBA. Конечно, можно найти и архивную копию (которая, внезапно, является более полной)... но вот я теперь думаю: это что, такой тонкий способ расширить определение VBA до "всё на свере, что есть в Windows", чтобы сделать реализацию этого невозможной третьей стороной? (Интересно, а под macOS как это работает в MS Office?)
Записан

С уважением,
Михаил Каганский
economist
Форумчанин
***
Offline Offline

Сообщений: 927


« Ответ #12: 1 Октябрь 2018, 19:22 »

eugenefoxx - повода для грусти нет. Любой "словарь" можно заменить двумерным массивом N*2. Да и других вариантов масса. Может стоит задуматься и выбрать что-то еще?   

Если я сталкиваюсь с 20k+ строками (а это предел "комфорта" и в Excel. и в Calc), - то сразу иду либо в СУБД (SQLite) или в Python с его сверхбыстрыми list, tuple, dictionary, написанных на языке С, с кучей методов поиска, сортировки, реверсного поиска итп. Также не стоит сбрасывать со счетов старый добрый CSV/TSV-формат, который читается и парсится на LOBasic и VBA почти одинаково быстро и уступает СУБД/Python считанные "разы" в скорости.   
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
eugenefoxx
Участник
**
Offline Offline

Сообщений: 17


« Ответ #13: 1 Октябрь 2018, 21:22 »

economist - спасибо за советы. Я это понимаю. Буду пробовать, т.к. не сильно упражняюсь в таких "занятиях". Хотелось на LOBasic, но пока еще решаю эту проблему для себя.
В целом задача простая. Как видно на примере VBA, на одной странице выбирается ключевой столбец с данными, считывается до конца строки, потом по нему в другом массиве, на другой странице, проводиться поиск необходимых значений, соответственно по такому же ключу. Т.е. тут сравниваются две базы данных, которые должны соответствовать другу другу. Не знаю, нужен ли для этого пример файла с данными. Тут можно все что угодно представить. Если будет хоть какое-то решение, буду благодарен. Допилю сам, лишь бы сдвинуться с мертвой точки. Как уже говорил, формулы я применяю, но тут по сути нужен скрипт для автоматической обработки, тем более массив информации большой.
« Последнее редактирование: 1 Октябрь 2018, 21:24 от eugenefoxx » Записан
economist
Форумчанин
***
Offline Offline

Сообщений: 927


« Ответ #14: 2 Октябрь 2018, 15:22 »

Скрипт/макрос, даже если массив огромен, может быть тут "однострочный", просто вставляющий готовую нужную формулу. Это выглядит примерно так:

[B1:B10000].FormulaLocal="=ВПР(ЧТО;ГДЕ;СТОЛБЕЦ;ЛОЖЬ)"

И будет то, что нужно - браться по ключу данные из другой таблицы и подставляться в имеющуюся.
Именованные диапазоны ЧТО ГДЕ - тоже можно задать макросом, или указать явно, например так [A2:A10000]

Макросы имеют один "побочный эффект" - они часто провоцируют "поток программирования" там, где это вовсе не нужно. Массивы, словари, циклы, сплошные области данных - это всё в данной задаче и VBA-коде - избыточно.

Формулой данная задача (построчное сравнение двух "перемешанных" таблиц) - решается примерно за минуту, именно столько на неё тратят мои коллеги, "не умеющие" макросы, но умеющие =ВПР().   
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
Страниц: 1 2 3 »   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!