Страницы: 1
RSS
PowerQuery ускорить обновление данных
 
Доброго дня.

Прошу помочь ускорить обновления данных по запросу в PowerQuery. Я новичок. Моя задача была создать файл аккумулирующий данные из разных ехсел файлов в один. Я создал запрос к папке, где хранятся файлы. В исходных файлах нужные значения находятся на разных листах исходников, поэтому я отсортировал нужные. Проблема - при добавлении нового файла в папку обновление запроса идет 2 минуты. Код запроса прилагаю.

let
   Источник = Folder.Files("M:\\Перевозки\2024"),
   #"Строки с примененным фильтром" = Table.SelectRows(Источник, each ([Extension] = ".xlsm")),
   #"Вызвать настраиваемую функцию1" = Table.AddColumn(#"Строки с примененным фильтром", "Преобразовать файл (2)", each #"Преобразовать файл (2)"([Content])),
   #"Развернутый элемент Преобразовать файл (2)" = Table.ExpandTableColumn(#"Вызвать настраиваемую функцию1", "Преобразовать файл (2)", {"Name", "Data"}, {"Преобразовать файл (2).Name", "Преобразовать файл (2).Data"}),
   #"Удаленные столбцы" = Table.RemoveColumns(#"Развернутый элемент Преобразовать файл (2)",{"Content", "Extension", "Date accessed", "Date modified", "Date created", "Attributes", "Folder Path"}),
   #"Сведенный столбец" = Table.Pivot(#"Удаленные столбцы", List.Distinct(#"Удаленные столбцы"[#"Преобразовать файл (2).Name"]), "Преобразовать файл (2).Name", "Преобразовать файл (2).Data"),
   #"Развернутый элемент Заявление" = Table.ExpandTableColumn(#"Сведенный столбец", "Заявление", {"Column4", "Column8"}, {"Заявление.Column4", "Заявление.Column8"}),
   #"Строки с примененным фильтром2" = Table.SelectRows(#"Развернутый элемент Заявление", each ([Заявление.Column4] = "Страховая сумма")),
   #"Развернутый элемент Сертификат" = Table.ExpandTableColumn(#"Строки с примененным фильтром2", "Сертификат", {"Column1", "Column3", "Column9"}, {"Сертификат.Column1", "Сертификат.Column3", "Сертификат.Column9"}),
   #"Строки с примененным фильтром3" = Table.SelectRows(#"Развернутый элемент Сертификат", each ([Сертификат.Column1] = "Вид транспорта:" or [Сертификат.Column1] = "Выгодоприобретатель:" or [Сертификат.Column1] = "Дата отправки" or [Сертификат.Column1] = "ИНФОРМАЦИЯ О ПЕРЕВОЗКЕ:" or [Сертификат.Column1] = "Наименование груза:" or [Сертификат.Column1] = "Номера и даты #(lf)перевозочных документов:" or [Сертификат.Column1] = "Описание транспорта (№):" or [Сертификат.Column1] = "Пункт назначения:" or [Сертификат.Column1] = "Пункт отправления:" or [Сертификат.Column1] = "Пункты перегрузки/место промежуточного хранения:")),
   #"Объединенные столбцы" = Table.CombineColumns(Table.TransformColumnTypes(#"Строки с примененным фильтром3", {{"Сертификат.Column9", type text}}, "ru-RU"),{"Сертификат.Column3", "Сертификат.Column9"},Combiner.CombineTextByDelimiter("", QuoteStyle.None),"Сведено"),
   #"Замененное значение" = Table.ReplaceValue(#"Объединенные столбцы","ИНФОРМАЦИЯ О ПЕРЕВОЗКЕ:","Страховая премия",Replacer.ReplaceText,{"Сертификат.Column1"}),
   #"Сведенный столбец1" = Table.Pivot(#"Замененное значение", List.Distinct(#"Замененное значение"[Заявление.Column4]), "Заявление.Column4", "Заявление.Column8"),
   #"Сведенный столбец2" = Table.Pivot(#"Сведенный столбец1", List.Distinct(#"Сведенный столбец1"[Сертификат.Column1]), "Сертификат.Column1", "Сведено"),
   #"Извлеченные первые символы" = Table.TransformColumns(#"Сведенный столбец2", {{"Дата отправки", each Text.Start(_, 10), type text}}),
   #"Измененный тип" = Table.TransformColumnTypes(#"Извлеченные первые символы",{{"Страховая премия", type number}, {"Дата отправки", type date}})
in
   #"Измененный тип"
 
Дмитрий Бухарин, сколько всего файлов и сколько листов\строк\ столбцов в нужных сводимых таблицах в каждом файле хотя бы приблизительно? 2 минуты как-бы и вполне норм, если в целом скажем сотни тыс. строк, много столбцов, много файлов...Кроме того, если каждый файл сам тяжелый и долго открывается, то PQ также долго его будет "открывать".
 
voler83, файлов чуть больше 100, в каждом файле 4 листа, столбцов примерно 20 (но не все имеют значения, большая часть пустые), строк от 40 до 100 (также не все имеют значения), размер файла до 300 Кбайт.
 
Дмитрий Бухарин, вроде не тяжелое все....но никто не знает, что у вас в функции "#"Преобразовать файл (2)" - вы же один файл-пример из папки обработали, на основе обработки создалась функция, и в том коде, который приложили, уже применяете эту функцию к др. файлам - так?  а что у вас в обработке первоначального файла -примера ? может там код на 1000 строк...
Изменено: voler83 - 02.05.2024 16:54:39
 
voler83, Прикладываю код функции "Преобразовать файл (2)" . Насколько я понимаю обрабатывается один файл, т.к. ссылка идет на книгу ехсел, а далее да уже ко всем файлам в установленной папке.
let
   Источник = Excel.Workbook(Параметр2, null, true),
   #"Строки с примененным фильтром" = Table.SelectRows(Источник, each ([Name] = "Заявление" or [Name] = "Сертификат")),
   #"Удаленные столбцы" = Table.RemoveColumns(#"Строки с примененным фильтром",{"Item", "Kind", "Hidden"})
in
   #"Удаленные столбцы"
 
Цитата
написал:
Table.Pivot
скинули бы вы весь свой файл, заменив данные на условные хотя бы - оч. трудно вертеть виртуально в голове. ИМХО скорее всего можно отфильтровать, и наверно и преобразовать данные в большом первом запросе до разворотов таблиц (до или сразу после шага  #"Развернутый элемент Преобразовать файл (2)", т.е. до pivot'a), обращаясь к вложенным таблицам, а разворачивать уже полностью готовое. Не знаю, ускорит это или нет выполнение запроса, наверно да, т.к. разворот таблиц, кажется, ресурсозатратное мероприятие. Остальное вроде все обычное, но pivot трудно понять без примера зачем.
Попробуйте сначала сами применить все преобразования к вложенным таблицам, если понимаете.  
Изменено: voler83 - 03.05.2024 12:51:07
 
voler83, к сожалению не понял вашей рекомендации с функцией "pivot". Отправляю тестовый файл и файл в котором создан запрос.

Информация, содержащаяся в данном сообщении, является конфиденциальной и предназначена исключительно для указанных получателей.
Несанкционированный доступ, распространение, копирование или дистрибуция этого сообщения или любых его вложений строго запрещены и могут быть незаконными.
Если вы не являетесь предполагаемым получателем, или если вы получили это сообщение по ошибке, пожалуйста, немедленно уведомите отправителя, ответив на это электронное письмо, а затем удалите его из вашей системы.
 
Цитата
написал:
не понял вашей рекомендации с функцией "pivot".
пока не смотрел файлы ваши, но:    #"Сведенный столбец" = Table.Pivot(#"Удаленные столбцы", List.Distinct(#"Удаленные столбцы"[#"Преобразовать файл (2).Name"]), "Преобразовать файл (2).Name", "Преобразовать файл (2).Data") - все эти операции и последующие можно применить к вложенным таблицам (которые появляются на шаге #"Строки с примененным фильтром" = Table.SelectRows(Источник, each ([Extension] = ".xlsm") ), не разворачивая их на шаге " #"Развернутый элемент Преобразовать файл (2)" - предположение, но возможно это увеличит производительность, если pivot вообще нужен....и вообще если 2 минуты так критично, то это (обработка вложенных таблиц) можно уже применить на этапе создания параметра обработки файла-примера наверно.
 
voler83, благодарю за комментарий, попробую, но буду признателен если посмотрите файлы и напишите новый комментарий.
 
Дмитрий Бухарин, попробуйте такой вариант - должно быть пошустрее, чем 2 минуты
m
Пришелец-прораб.
 
Дмитрий Бухарин,
upd all
сделал все через обращение ко вложенным таблицам
копи-пастом размножил файл "Тест_файл.xlsm" на 1187 файлов - обновляется за 20 секунд на i5-10500t 32Gb RAM
110 файлов ("чуть больше 100") обрабатываются за 4 секунды

Для демонстрации, что все работает для любого кол-ва файлов в папке, я сделал копипаст вашего файла "Тест_файл.xlsm" - добавился файл "Тест_файл — копия.xlsm", измените путь к папке с файлами соответственно.

п.с.1: мне кажется, основные тормоза у вас и были из-за pivot'a и последующих множественных разворотов туда-сюда, при которых вложенные таблицы появились во всех строках - наверно, они занимают больше памяти. У меня вообще нет разворотов.

п.с.2: но предполагается, что у вас структура таблиц всегда одинаковая, в противном случае до обращения к соотв-м полям и значениям вложенных таблиц надо добавить столбцы индексов, прописать какие-то условия для получения нужного № строки =№ индекса, и по № индекса обращаться к строкам влож. таблиц. Но это не увеличит время обработки сколько-нибудь существенно.
п.с.3: код AlienSx работает почти секунда в секунду на указанных кол-вах файлов.
Изменено: voler83 - 05.05.2024 16:16:46
 
voler83, Спасибо за Ваш ответ. Я научился извлекать нужные мне значения в новые столбцы без функции "pivot"  :)  Только можно ли добавить нужные столбцы одним шагом, а не выполнять для каждого нового столбца новый шаг?
 
AlienSx, Спасибо за Ваш ответ, но у меня к сожалению не получилось разобраться в коде и поэтому в дальнейшем трудно будет работать если вдруг что пойдет не так.
 
Дмитрий Бухарин, можно почти все, написать свою функцию и даже не одну, если ради теории - погуглите и поищите на форуме что-то вроде "автоматизированное добавление столбцов в power query" - точно попадалось, но поскольку у меня вручную вбиты номера строк и имена столбцов, то в любом случае вы должны будете также вручную менять параметры функции или составить списки готовых параметров также вручную заранее - в коде Alien это примерно сделано.
Я же не через кнопку добавления столбца конечно каждый столбец добавлял, а раскопировал в расширенном редакторе шаг Table.AddColumn сразу на нужное кол-во столбцов и менял только номера строк и название предыдущего шага.
п.с.: а в коде Alien стоит разобраться ;)
Изменено: voler83 - 13.05.2024 18:33:58
 
voler83, Спасибо за комментарий. Буду разбираться и пробовать
Страницы: 1
Наверх