Бегло глянул - по моему, они очень не любят, когда их парсят :-) За Excel в данном случае не подскажу, к сожалению.
Но так как спрашивали про "посильную помощь" - у меня была схожая задача, только парсить надо было 15 сайтов, в общей сумме ~240 ссылок, где из каждой извлекалось довольно много данных по определенным условиям. А потом это уже паковалось в Excel и так далее. Решение сделал с помощью RPA (Robotic Process Automation), в данном случае Automation Anywhere (есть бесплатная community версия). Но на рынке over 9000 их - из известных UIPath, BluePrism и так далее. Они достаточно просты в освоении, не требуют знания языков программирования и в целом интуитивно понятны.
В АА очень прилично реализована работа с Excel - оно без проблем умеет открыть, считать список задач (в данном случае имен для поиска), а потом записать результаты в любой удобной форме.
Камиль Гусейнов написал: Попробовал Ваш вариант, просчет идет до 25 строки, столько же строк было в тестовом файле, к сожалению не нашел в макросе, что подправить, чтобы он прошел до конца.
Хм, действительно, забавно. Переменная EndRow определяется по первой колонке и возвращает 25 строк, надо потом глянуть почему Пока можно заменить EndRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row на EndRow = ws.UsedRange.Rows.Count
New написал: Ну, раз больше никто не предлагает вариантов, то я остановлюсь на ваших формулах.
Уф, зарекался же на ночь задачки брать посмотреть.. Попробовал вот так, 200 тысяч строк обрабатывает где-то полторы минуты. Понятно что PQ всяко быстрее будет, но чисто академический интерес заел. Тут вся работа пока в рамках одного листа, вынос результата с ЛОЖЬ на другой лист не делал - в 4 утра пока неохота
Код
Sub fast_count()
Dim ws As Worksheet
Dim EndRow As Long
Set ws = ThisWorkbook.Worksheets("Дубли физ лиц")
Set ID_Dict = CreateObject("Scripting.Dictionary")
Set Identity_Dict = CreateObject("Scripting.Dictionary")
StartTime = Timer
IDColumn = 3
IdentityColumn = 9
EndRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
StartRow = 2
ws.Range("I2:I" & EndRow).Formula = "=CONCAT(D2:G2)"
For i = StartRow To EndRow Step 1
Identity = Cells(i, IdentityColumn).Value
If Identity_Dict.Exists(Identity) Then
Identity_Dict(Identity) = Identity_Dict(Identity) + 1
Else
Identity_Dict.Add Identity, 1
End If
ID = Cells(i, IDColumn).Value
If ID_Dict.Exists(ID) Then
ID_Dict(ID) = ID_Dict(ID) + 1
Else
ID_Dict.Add ID, 1
End If
Next
IDKeys = ID_Dict.keys
IDCount = ID_Dict.items
IdentityKeys = Identity_Dict.keys
IdentityCount = Identity_Dict.items
For j = 2 To EndRow
For i = LBound(IdentityKeys) To UBound(IdentityKeys)
If ws.Cells(j, IdentityColumn).Value = IdentityKeys(i) Then
ws.Cells(j, 10).Value = IdentityCount(i)
Else
End If
Next i
For p = LBound(IDKeys) To UBound(IDKeys)
If ws.Cells(j, IDColumn).Value = IDKeys(p) Then
ws.Cells(j, 11).Value = IDCount(p)
Else
End If
Next p
If ws.Cells(j, 10).Value = ws.Cells(j, 11).Value Then
ws.Cells(j, 12).Value = True
Else
ws.Cells(j, 12).Value = False
End If
Next j
Columns(9).EntireColumn.Delete
MsgBox "Done. ", , Round(Timer - StartTime, 2) & "s"
End Sub
Спасибо, исправил. Название.. я использовал +- то, по чему предположительно человек будет гуглить. Можно конечно поменять на "Надстройка для использования SQL запросов в Excel", или что-то такое, но как мне кажется, "находимость" такой фразы будет ниже. Но спорить не буду, может кто-то что-то предложит еще.
Вроде как не в курилку, потому что не оффтоп, но вроде как и не вопрос, а просто показать что обнаружил :-)) Если сильно промазал, надеюсь модераторы перенесут.
Какое-то время назад столкнулся с тем, что результат объединения двух или более таблиц и подсчета значений (например суммы колонки) нужно вывести в одну ячейку - и это потянуло за собой необходимость поковырять PowerQuery - что само по себе хорошо, но по сравнению с привычным SQL показалось не очень удобным. Да и толи PQ не умеет возвращать не таблицу, а именно single cell, толи я тупой и не разобрался - в общем задачу то решил, но на протяжении всего процесса было стойкое ощущение нехватки просто возможности написать select sum(field) from table t
Начал гуглить, ничего особо интересного не нашел, кроме каких-то хитрых способов через data connection wizard - показалось не очень удобным.
Попробовал - именно оно, то что и искалось. Возможность прямо в ячейке писать запрос к данным, форматированным как таблица, типа
Код
=Windy.Query("SELECT sum(ID) FROM Таблица1")
Подумал, что может кому-то интересно будет тоже. Да, применимость местами узкая - без надстройки файл с использованием этой функции не передать, работать не будет, но для каких-то локальных вычислений / дел показалось весьма годным.
New, спасибо Я погряз в работе, глянуть все равно особо не мог.
Правда смутило - а что значит "по всему столбцу"? У меня вроде работало только при клике на конкретную ячейку.. Даже открыл сейчас и поигрался - никакие выделения столбцов не приводят к записи коммента, только прямой клик на ячейку.
Данные из ответа это просто для примера, что при обращении по указанным вами параметрам ответов из БД по транспортным средствам может быть больше чем 1. А это немного меняет задачу - потому что теперь нужно не просто пройтись по справочнику и извлечь конкретную модель по уникальным ключам, а еще вывести пользователю возможность каким-то образом выбрать - а значит ему нужно что-то показать, например, на основании чего он сделает свой выбор.
По производительности не скажу, под рукой подходящего файла нет. Можете попробовать написать простейший макрос, который например пробегает от первой до последней строки и сравнивает три ячейки, и если совпало добавляет, не знаю, единицу на счетчик.. По идее 130к это не о чем, должно быть довольно быстро. Единственное что поиск по подстроке модели, может добавить времени, но опять же, в рамках 130к строк подозреваю не существенно. Надо пробовать
Если в форме, которую заполняет пользователь он забил например Largus, 106 лс, 2019 год выпуска, то при поиске по этим трем параметрам, у меня будет возвращено минимум два этих варианта - см. табличку. Т.е. судя по всему именно трех этих параметров слегка может быть недостаточно, для однозначной идентификации GUID
Как собрать данные с разных листов, с определенных столбцов в отдельную книгу, Собрать данные с разных листов, с определенных столбцов в отдельную книгу
Изящненько.. Я на коленке собрал сначала в том же воркбуке на Лист "All", а потом потом подумал что обновлять и содержать это вообще уныло будет.
В задаче про плавающую колонку не очень понятно - на примерах она последняя всегда. Но на всякий случай вкрутил перебор для поиска.
Код
Sub collect_info()
Dim ws As Worksheet, LastColumn As Long, LR As Long, LR_ALL As Long, All As Worksheet
Set All = ActiveWorkbook.Worksheets("All")
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = "All" Then
GoTo finish
Else
LastColumn = ws.Cells(11, ws.Columns.Count).End(xlToLeft).Column
LR = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
LR_ALL = All.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
ws.Range("B11:C" & LR).Copy _
Destination:=All.Range("A" & LR_ALL)
End If
For i = 1 To LastColumn
If ws.Cells(1, i).Value = "ПОЛНОЕ НАИМЕНОВАНИЕ" Then
ws.Range(ws.Cells(11, i), ws.Cells(LR, i)).Copy
All.Range("C" & LR_ALL).PasteSpecial xlPasteValues
End If
Next i
finish:
Next
End Sub
БМВ написал: На доступ к таким ресурсам требуется очень незначительный канал
Сильно, конечно, зависит от.. Если чисто приложения еще более менее, а вот если нужен именно рабочий стол - к каналу все таки требования довольно сильные, как по скорости, так и по уровню задержек. Пробовал разные инстанции в aws / google cloud, на RDP работать конечно можно, но спустя час отсутствие плавности начинает подбешивать ) При том что канал 100 мегабит, задержки в тот же франкфурт терпимые.. Сейчас спасает то, что в google cloud инстанция на которой у меня RPA решение живет не так уж часто приходиться дергать Один раз настроил и работает себе.
Можно назвать как-то типа: "Перенос данных между таблицами с помощью макроса", формулами все равно никто не предложил, а лучше ничего в голову не приходит
Я использую на работе корпоративный Office365. По сути у него есть два варианта - использование именно онлайн в браузере или установка Desktop версии. В 95% случаев я использую только второй вариант, поскольку в первом отсутствует довольно большое количество формул, которые доступны в десктоп.
Точного списка я не нашел, но натыкался на какие-то ограничения постоянно, поэтому плюнул и стал использовать только десктоп. Онлайновый максимум для обмена какими-то простыми доками с возможностью совместной работы.
Формулами не знаю, учитывая что там наверняка еще длинная колбаса других контрагентов - я чет не люблю к такому привязываться формулами, видимо не настолько хорошо знаю Excel. Макросом - решаемо, сделал, работает. Сколько будет контрагентов и машин не важно, пока оно заполняется в том же виде, в котором оно заполнено сейчас. Но насколько этично выкладывать готовый результат - не знаю, тут вопрос не в конкретной проблеме, а комплексная задача - поэтому насколько я успел увидеть, такое отправляют в работу :-)) Отберу случайно хлеб у кого-то, поколотят еще.. ))
В общих чертах - можно сделать макрос, который построчно берет все из таблички "база", ищет контрагента на странице бух, в нем ищет нужное сочетание тариф+номер, запоминает строку, а потом перебирает все коды с обоих страниц и соотв. копирует значения.
В бесплатной версии JavaScript API и HTTP API Геокодера установлен лимит на общее число запросов. Запросы в считаются суммарно по следующей формуле:число запросов в Геокодер + число запросов в Маршрутизатор + 5 × число запросов к Панорамам. Их количество не должно превышать 25 000 в сутки, из которых количество запросов к HTTP API Геокодера не должно превышать 1000 в сутки. (с) яндекс
Можно еще в Waze посмотреть, OpenMap и тд - только с большое долей вероятности зарегаться и получить ключ надо будет в любой из них. Ну и скрипты перепиливать все.
Но на самом деле не вижу в чем заморочка с ключем. Получить его привязав виртуальную карту пустую к гуглу дело 5 минут, макросы свои отредактировать после этого тоже не шибко сложно.
Эх, опередили, пока домой добирался )) Я бы еще наверное вкрутил бы убирание комментария если в ячейке уже нету ошибки (тоже по клику), чтобы потом не смущал пытливые умы - но это надо осторожно, если комментарии больше нигде не используются.
TokarevP написал: Код работает, но запрос по прежнему отклонен.
Он и не будет работать, повторюсь. Без API ключа, которого у вас нет, судя по всему google map service больше не работает. Зарегистрируйте аккаунт в гугле, привяжите карту, гугл вам выделит лимит в $200 ежемесячно (эти деньги не будут списываться с карты). Вы сможете сгенерировать API ключ, который добавите в свои ссылки в макросе &key=APIKEY и будет вам счастье, даром, для всех, и никто не уйдет обиженным.. (с)
You must have a valid API key and a billing account to access our APIs. When you enable billing, you will get $200 free usage every month for Maps, Routes, or Places. Based on the millions of users using our APIs today, most of them can continue to use Google Maps Platform for free with this credit. Having a billing account helps us understand our developers’ needs better and allows you to scale seamlessly.
Иными словами - "дайте денех!" видимо халява кончилась. Плохо вчитался. Ключ нужен, дадут его бесплатно и даже будет какой то лимит использования (который поди под ваши задачи хватит с головой), но для этого нужно настроить аккаунт с биллингом в гугле.
Если посмотреть в дебаге какие ссылки оно дергает обращаясь к гуглу, то получаем вполне стандартный ответ - You must use an API key to authenticate each request to Google Maps Platform APIs. В коде я передачи гуглу апи ключа вообще не увидел, оно просто дергает ссылку
А добавить колонку вообще не вариант? Сделать текущую "Сумма продажи" - "Сумма продажи в валюте резидента", а рядом добавить "Сумма продажи в рублях", ну а дальше =ЕСЛИ([@[Тип клиента]]="Нерезидент",ВПР([@Дата],Таблица2,2,ЛОЖЬ)*[@[Цена продажи в вал.резидента]],C3) - тогда по месяцам сумму незамысловато подсчитать. Формулой без доп. колонки в голову не пришло ничего, подпишусь, вдруг опишут что-то интересное
Я что-то может ночью совсем уж тупой, но я в упор не понимаю.. Есть ячейка A1. В ней есть какие-то значения - это понятно. На основании этого значения хочется вывести другое значение? Куда? В ячейку B1 например? А что там в итоге хочется получить, 100 или "Правильно"? Ну т.е. =ЕСЛИ(A1=0, "Правильно", "Неправильно") чем не подходит?
Тут наверное все же в первую очередь вопрос получается не КАК посчитать, а ЧТО и главное ЗАЧЕМ Если на это будут ответы (я имею ввиду для самого себя ответы, не для форума), тогда вопрос КАК решится довольно быстро.
Например если задача стоит посчитать, на сколько в среднем задерживается доставка - можно просто из фактического времени прибытия вычесть ожидаемое время и увидеть проблему в целом. Сколько таких случаев, на сколько в среднем опаздывают, кто именно, и так далее. А потом уже в конкретные случаи можно углубиться и разобраться.
Задача может быть и в контроле каждого из этапов, так сказать более детально и развернуто. Тогда для каждого элемента бизнес процесса необходимо определить норматив - предел времени который может быть затрачен на этот шаг, потом считать во сколько было начало этого процесса, конец процесса, на сколько по времени было отклонение от начала и от конца, сколько времени занял сам процесс и т.д. И да, тут тогда можно будет посчитать %% отклонение от норматива - но для этого надо все вышеперечисленное.. Человек может укладываться в норматив, но стабильно опаздывать на полчаса на погрузку и заканчивать ее на полчаса позже ожидаемого времени для этого этапа