Она позволяет создать список кратный одному дню от начала даты. В моём случае нужно сделать аналогичное, но даты должны будут выбраны такие, которые соответствуют определённому дню недели. Вот и думаю, как можно причесать данный запрос? Может разложить список от начала и конца даты, затем определить день недели и потом по условию удалить ненужные дни. Подскажите, как бы поаккуратнее так сделать? Спасибо.
AlexMakarov написал: может разложить список от начала и конца даты, затем определить день недели и потом по условию удалить ненужные дни.
А генерацию по заданным дням недели? Или, учитывая входной массив, скорее всего явно пересекающийся по датам, то генерация календаря, а затем связывание по дням недели и ограничением по диапазону дат?
Цитата
AlexMakarov написал: Подскажите, как бы поаккуратнее так сделать?
Увы, единственно верного учения для этого класса задач нет. В каких-то случаях так, в каких-то этак или ещё как-то. Сильно зависит от структуры данных и объёма генерации. Если у вас сотня другая таких строк, то без разницы в общем-то. Вам очень важно, что один алгоритм решает за 0,1 секунды, а другой 0,2 секунды?
let
Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
types = Table.TransformColumnTypes(Source,{{"Начало", type date}, {"Окончание", type date}, {"По каким дням недели", type text}, {"Номер", type text}}),
add = Table.AddColumn(types, "list", each let a = List.Transform(Text.ToList([По каким дням недели]),Number.From)
in List.RemoveNulls(
List.TransformMany(List.Dates([Начало],Number.From([Окончание]-[Начало])+1,#duration(1,0,0,0)),
(x)=>{Date.DayOfWeek(x)},
(x,y)=>if List.Contains(a,y+1) then x else null)))
in
add
Коллеги, всем спасибо, всё получилось. PQ только начал осваивать, и вижу, что отстал в этом вопросу. Подскажите, Вы код писали, сперва изучив архитектуру "M"? Просто интересно.
Вывод: 2 варианта с генераторами требуют доработки напильником (свой запрос я уже подправил, он в некоторых случаях не выходил из цикла, но количество строк все равно не верное), но какой-то явной критики по быстродействию все равно нет. Промежутки между датами генерил рандомом, 0-50 дней, если дней делать больше, то количество строк при развороте заваливало за 1кк.
PooHkrd написал: как вы замеряете время выполнения запроса?
Простым макросом
Код
Public Sub testSpeed()
Dim pLo As ListObject, t As Single
t = Timer
Set pLo = ActiveSheet.ListObjects(1)
pLo.QueryTable.Refresh False
MsgBox CStr(Timer - t)
End Sub
Предполагается, что умная таблица результата запроса на активном листе единственная.
Цитата
PooHkrd написал: так и по количеству выводимых строк.
Правильность выполнения ограничений не проверял - ТС не позаботился представить пример с учётом слева/справа. Всё как всегда - это обязанность отвечающих учитывать все нюансы.
PooHkrd написал: Так, объясните нулю в ВБА, куда этот макрос копировать, и как он активируется? сам при обновлении запроса? Или надо еще что-то нажимать?
Так, одна тема - один вопрос!
PS В книгу макросов, при запуске он сам вкл. "Умную таблицу", а по завершении - сообщает время выполнения. Ну, как и с секундомером, в общем
Всё сложное - не нужно. Всё нужное - просто /М. Т. Калашников/
Хе, хе - некорректная постановка интервалов, однако. Следовательно вопрос к адекватности постановщика. Смысл создавать такое? Может ещё отслеживать случай, когда начало больше окончания?
AlexMakarov написал: У меня вопрос, а обязательно создавать таблицу? Попробовал этот запрос на "подключении" и ошибка в синтаксисе.
Нет, не обязательно. Если у Вас ошибка в синтаксисе, вероятнее всего, одно из двух: либо Ваша таблица / столбцы называются как-то иначе, либо Вы не в полном объёме вставили код в расширенный редактор.
были мозги всякой фигней забиты, сейчас про эту тему вспомнил, еле нашел как-то так получилось
Код
let
Source =
Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
ExactDates =
Table.AddColumn(
Source,
"Даты",
each let
a = Date.StartOfWeek([Начало]),
b = [Окончание],
c = List.Buffer(List.Transform(Text.ToList(Text.From([По каким дням недели])),Number.From)),
d = List.Count(c)
in
List.Skip(
List.Generate(
()=> [ i=1,
e=Number.Mod(i-1,d),
f=a,
g=Date.AddDays(f,c{0}-1) ],
each [g]<=b,
each [ i = [i]+1,
e = Number.Mod(i-1,d),
f = if e<=[e] then Date.AddDays([f],7) else [f],
g = Date.AddDays(f,c{e}-1) ],
each [g]
),
(h)=>h<[Начало])
),
Expand =
Table.TransformColumnTypes(
Table.ExpandListColumn(ExactDates,"Даты"),
{{"Даты", type date}}
)
in
Expand
PooHkrd, а все-таки, понять бы, количество выводимых строк совпадает только в двух случаях. Где неправда? Сколько должно быть и на чем ошибки? Вот что интересно...
У себя в коде нашел косяк в расчете переменной RealStart, там я проверяю равен ли день недели начальной даты диапазона одному из искомых в списке от пользователя, и если не равен, то нахожу ближайший следующий. Код заменил на корректный в своем посте №6. В результате количество строк вывода стало равным предыдущему моему коду где просто генерились промежутки и из них List.Select'ом выковыривал нужные дни. В вашем коде ковыряться честно говоря времени нет, посему если есть желание, то можете по-дебажить самостоятельно. Наверняка также ошибка в условиях входа либо выхода. Файл-полигон прилагаю, там сразу увидите на какой строке начинаются расхождения с корректными алгоритмами. Кстати, после избавления от глюка мой код и выполняться стал шустрее. Добавляю в итоговую таблицу генератор от Андрея Лящук и скорректированные данные по моему генератору.