Добрый день! Помогите понять, плиз, в чём тут дело. Есть некий изначальный список значений в колонке "Вид транспорта" в моей модели (см. первую картинку во вложенном файле). Далее следует их фильтрация для удаления строк с 2 значениями по направлению АВИА: = Table.SelectRows(#"Развернутый элемент NewColumn4", each not Text.Contains([Вид транспорта], "САМОЛЕТ") and not Text.Contains([Вид транспорта], "АВИАКАРГО")). Ожидаю увидеть в результате ВСЁ, кроме этих двух значений. Но по факту вижу, что кроме "САМОЛЕТ" и "АВИАКАРГО" также пропали строки со значением "(NULL)" (см. вторую картинку во вложенном файле) Вопрос, почему, собственно? из-за этого потерялось 807 строк.... Заранее благодарю, кто откликнется
Артур - зачем мухлюете? Вопрос был про null, а не его представление в списке выбора.
Код
Table.SelectRows(
Table.FromRecords({
[CustomerID = 1, Вид транспорта= "САМОЛЕТ", Phone = "123-4567"],
[CustomerID = 2, Вид транспорта= null, Phone = "987-6543"] ,
[CustomerID = 3, Вид транспорта= "АВИАКАРГО", Phone = "543-7890"] ,
[CustomerID = 4, Вид транспорта= "Ringo", Phone = "232-1550"]
}),
each not Text.Contains([Вид транспорта], "САМОЛЕТ") and not Text.Contains([Вид транспорта], "АВИАКАРГО")
)
GaliyaF, Table.SelectRows использует внутри логическое выражение, если его результат true - берём строку в результат, если false - не берём. А теперь упростим, подумайте, что получается?
Код
let
a = null,
r1 = Text.Contains(a, "foo"),
r2 = Text.Contains(a, "goo"),
not_r1 = not r1,
not_r2 = not r2,
trueTest = (not_r1 and not_r2) = true,
falseTest = (not_r1 and not_r2) = false
in
falseTest
Андрей VG, здравствуйте. так я сначала хотел занести null, но решил не отклоняться от предложенного в описании если честно, то не знал что и null исключит
Код
let
Source = Table.FromRecords({
[CustomerID = 1, Вид транспорта= "САМОЛЕТ", Phone = "123-4567"],
[CustomerID = 2, Вид транспорта= null, Phone = "987-6543"] ,
[CustomerID = 3, Вид транспорта= "АВИАКАРГО", Phone = "543-7890"] ,
[CustomerID = 4, Вид транспорта= "Ringo", Phone = "232-1550"]
}),
#"Replaced Value" = Table.ReplaceValue(Source,null,"===",Replacer.ReplaceValue,{"Вид транспорта"}),
#"Filtered Rows" = Table.SelectRows(#"Replaced Value", each not Text.Contains([Вид транспорта], "САМОЛЕТ") and not Text.Contains([Вид транспорта], "АВИАКАРГО")),
#"Replaced Value1" = Table.ReplaceValue(#"Filtered Rows","===",null,Replacer.ReplaceValue,{"Вид транспорта"})
in
#"Replaced Value1"
StatuS, Вполне очевидные. Просто нужно внимательно читать описание функции в справочнике
Цитата
Text.Contains(text as nullable text, substring as text, optional comparer as nullable function) as nullable logical
Обратите внимание на выделенное жирным, т.е. функция может возвращать 3 значения true/false/null. А уж как работает Table.SelectRows тут и думать не надо. Другой вопрос, если справочники не читать и работать в кнопочном режиме, то, поверьте, вас ждет еще огромная куча "неочевидных" результатов. Это не говоря про банальные баги, которые вообще нигде не задокументированы, а вы, возможно, уверены, что все работает чудесно.
PooHkrd, ну тут вопрос в опыте и наработке "шишек". Я, например, с PQ меньше месяца работаю - поэтому для вас этот момент очевиден, как и для Андрей VG, а для меня нет. А про:
Цитата
PooHkrd написал: Просто нужно внимательно читать описание функции в справочнике
Полностью согласен, внимательность нужна во всем. Но проснулась она почему-то только после наглядного примера
StatuS написал: Я, например, с PQ меньше месяца работаю
Хорошо, даю лайфхак: если вы жмете кнопку, и PQ сделало с виду правильную для вас трансформацию данных - рано радоваться. В первую очередь смотрим на формулу получившегося шага, потом открываем справочник, и тщательно изучаем, что за функции используются в ней. Для порядка эти функции можно погуглить и почитать что пишут про них корифеи и как жалуются на них на сайте поддержки M$. Еще можно поискать по данному форуму, не жаловался ли кто-нибудь на какие-то глюки? И если все чисто - работаем дальше.
PooHkrd написал: если вы жмете кнопку, и PQ сделало с виду правильную для вас трансформацию данных - рано радоваться. В первую очередь смотрим на формулу получившегося шага, потом открываем справочник, и тщательно изучаем, что за функции используются в ней. Для порядка эти функции можно погуглить и почитать что пишут про них корифеи и как жалуются на них на сайте поддержки M$. Еще можно поискать по данному форуму, не жаловался ли кто-нибудь на какие-то глюки? И если все чисто - работаем дальше
простите, а сколько времени тогда я буду делать задачку, которую надо сделать за 5 минут? я не студент, у меня нет времени всё подробно изучать, к сожалению! я могу в работе использовать готовые решения, надеясь, что они работают с достаточной степенью точности.
Можете так не делать. Согласовано! Работайте как знаете - только за результаты расчетов будете отвечать вы, а не M$ Лично я пару раз криво посчитал, еще до PQ, тупо функциями и сводными, потому что не до конца знал как ими правильно пользоваться, и ответил. Мне не понравилось. Пришлось после работы учиться вместо погулять, а вы как знаете. А еще не нужно так бездумно цитировать - придут модератры и расстроятся. А у них очень тонкое душевное устройство - не нужно их расстраивать.
Андрей VG написал: GaliyaF , Table.SelectRows использует внутри логическое выражение, если его результат true - берём строку в результат, если false - не берём. А теперь упростим, подумайте, что получается?
Андрей, добрый день! я даже не представляю, как проверить предложенный Вами код. Я не создавала код и не прописывала эту функцию "вручную" - я использовала стандартный инструмент фильтрации - а эту формулу PQ сам прописал автоматически. Но если я просто отфильтрую по значению "null" - то получу список из этих самых "потерянных" 807 строк - PQ же не ругается на это, не выдаёт ошибок или пустую таблицу, значит, если написано = (null), то его устраивает, а проблема возникает, когда используются операторы сравнения <>, да?
GaliyaF, null - это не текст, соответственно он не может в себе иметь значение "Самолет" или какое-либо другое. Это просто тип данных, которые обозначает отсутствие какого-либо значения как такового. Посмотрите на разницу обозначений в коде Андрей VG,
GaliyaF написал: когда используются операторы сравнения <>, да?
Нет, когда в логическое выражение добавляется обработка ваших данных функциями и на выходе этих функций может быть значение отличное от true/false. Вот тут как раз вылезла функция Text.Contains которая на выходе может выдавать как true/false, так и null, и вот этот null по сути функцией Table.SelectRows был обратботан как false. Именно поэтому не прошли строки с null - вылез подводный камень.
GaliyaF написал: Я не создавала код и не прописывала эту функцию "вручную" - я использовала стандартный инструмент фильтрации
Какой? Вы так и будете продолжать стесняться и не выкладывать информацию? Кому нужно решение вашей задачи - форумчанам? Не уверен. Сделал по примеру, любезно предоставленному artyrH, исключение в фильтре слов САМОЛЕТ и АВИАКАРГО - не получил ваш код, и, соответственно, исчезновения строк с null
Код
let
Source = Table.FromRecords({
[CustomerID = 1, Вид транспорта= "САМОЛЕТ", Phone = "123-4567"],
[CustomerID = 2, Вид транспорта= null, Phone = "987-6543"] ,
[CustomerID = 3, Вид транспорта= "АВИАКАРГО", Phone = "543-7890"] ,
[CustomerID = 4, Вид транспорта= "Ringo", Phone = "232-1550"],
[CustomerID = 1, Вид транспорта= "ТРАКТОР", Phone = "123-4567"],
[CustomerID = 2, Вид транспорта= null, Phone = "987-6543"] ,
[CustomerID = 3, Вид транспорта= "ДИВАН", Phone = "543-7890"] ,
[CustomerID = 4, Вид транспорта= "АЭРОПЛАН", Phone = "232-1550"]
}),
#"Filtered Rows" = Table.SelectRows(Source, each ([Вид транспорта] <> "АВИАКАРГО" and [Вид транспорта] <> "САМОЛЕТ"))
in
#"Filtered Rows"
Алексей, спасибо. Наученный SQL - если есть null, то всегда делаю в коде на него проверку на него, а уж потом всё остальное Теоретически можно писать разработчикам. По идее, не должна Text.Contains возвращать null, если текст где ищем null. Но тут у всех свои взгляды. Это как с Join при JoinKind отличном от Inner - столбцы ключей должны иметь разные имена, а собственно почему? Почему не брать данные только ключевых столбцов левой таблицы, в правой же там где нет, то и нет значений, а там где есть - они равны, как при Inner. Загадки разрабов, однако
Андрей VG написал: Это как с Join при JoinKind отличном от Inner
немного оффтопа: Вот она, моя боль! Замучился уже удалять ключевые столбцы после джойнов и переименовывать их до джойнов. Вот прямо зла не хватает. Делов-то необязательный параметр сделать, мол по умолчанию ключевые столбцы не добавлять в итог, но если хочется, то пишешь в параметр true и они там. Но нет, куда там. А NestedJoin уже в принципе не использую, разворачивание столбцов на больших массивах отнимает слишком уж до фига времени.