Pull to refresh

Comments 168

OLAP - это про аналитику, а регистры - про OLTP. Хотя результат похож. Но регистры сведений - это скорее просто обертка надо SELECT LIMIT (TOP) 1, а регистры накоплений - над SELECT SUM/MAX. Но это все равно очень частный случай (хоть и самый встречаемый). В более общем случае это бы выглядело как-то так.

Производитель: Вот молоток, им можно забивать гвозди.

Автор: Вот тупой производитель, ведь мне иногда надо вытаскивать гвозди, а молоток этого не умеет!

Только он забивает гвозди только 10 см. в длину. А 8 см. и 12 см. не забивает. Но называется молотком. И человек берет его в руки и ожидает, что его 12 см. гвоздь будет забит

То, что человек ожидает чего-то странного, не заложенного производителем - это проблемы самого человека. Не надо ожидать по умолчанию от молотка возможностей выдергивать гвозди, даже если другие производителя обеспечивают свои молотки такой возможностью.

Что странного в том, чтобы ожидать что срез последних будет выдавать последние записи, а не все подряд?

Так он и выдаёт последние записи по комбинации значений всех измерений. Нигде в документации от 1С не сказано, что срез последних будет работать, если выбирать не все измерения.

Но и обратное нигде не сказано. Вот дословная цитата из документации:

"Предназначена для получения наиболее поздних записей регистра сведений на указанную дату (включительно). Включает только активные записи. По каждой комбинации измерений будет найдена наиболее поздняя запись, но не более поздняя, чем указанная дата."

Вот претензия к качеству документации обоснована, тут вопросов нет.

Почему это не умеет? Плотницкий молоток прекрасно умеет дергать гвозди.

Регистры - это обертка на sql запрос, а не на таблицу и обертка удачная. Но таких находок в 1с - раз, два и закончились и случились они в прошлом веке.

К регистрам есть ещё объектная модель доступа, это довольно удобно, потому что можно одной строкой получить то, что нужно, а кроме того, она избавлена от Null. Но вот, как, например, объяснить то, что «найти последнее» в переодическом регистре, возвращает только ресурсы, то есть когда это последнее, вы узнать не можете. Про кучу ограничений в объектной модели, типа вы должны указать все измерения или работать только с индексируемыми полями я молчу. Помимо ресурсов, вроде бы, ещё есть реквизиты в регистрах, тоже странная вещь, про которую хочется спросить: нахрена?

P. S. В статье не раскрыто о переодичности переодических регистров, типа в пределах секунды, минуты и т.п. Вообще, я бы сказал, что нам «гонит дичь», человек который просто не до конца понимает что и как и хочет разложить это у себя по полочкам, но выдаёт за какое-то откровение.

P. P. S. Не могу часто писать, но спустился по комментариям ниже и немного подахренел. Уважаемый автор, логика платформы 1С предельно ясна: вы не можете взять срез по 1му измерению, вы не можете взять срез по 2 измерениям, вы просто берёте срез. Измерения указаны при создании регистра, именно по ним и берётся срез, если их два. то это будет срез по 2 измерениям, если был создан регистр с 3мя измерениями, то это будет срез по 3м. Таким образом, вы путаете фильтр, в котором вы задаёте что выводить из полученного среза (сейчас не помню, вроде бы он применяется на данные до взятия среза) и какие-то мифические динамо-срезы, которых тут и в помине нет. Если вам нужен срез по 2м измерениям в регистре из 3х, то GoTo handmade.

Не могли бы пояснить: что именно я, по-вашему, не понимаю?

Например, то, что периодичность можно выставить в "По позиции регистратора". Это и даст вам то, чего вам, по вашему, недодали: уникальность даты.

Платформа - это инструмент. Если вы молотком попали себе по пальцу, это вовсе не значит, что молоток - плохой инструмент.

И часто вы таким образом меняете типовые конфигурации ради одного отчета?

У вас претензии к конфигурации, а в статье вы ругаете платформу.

Почему в данном случае вы на Windows не агритесь? Windows в данной ситуации виновата не меньше, чем платформа 1С.

Нет. У меня претензия именно к платформе. Я хочу, чтобы если таблицу назвали срезом последних, мне последние записи и выдавали

Они не совсем корректно сделали описание для запросов, но сама концепция работает в рамках их яп.

В запросах есть срез последних и срез первых, срез последних выдаст все записи, которые были сформированы после определенной даты, срез первых выдаст наоборот до конкретной даты.

Кроме самих sql запросов, в 1с есть возможность обрабатывать и работать с бд и средствами языка программирования 1с, например регистрысведений.ЦеныНоменклатурыКонтрагентов.СрезПервых(дата("20200101"), какой то отбор по номенклатуре и контрагентам); И при подобном обращении он уже ведет себя, как и предполагал автор топика, это конечно странно и не логично устроенно, что в запросах он себя ведет не так как ожидаешь увидеть

Объектная модель точно так себя ведет? Проверяли?

Нет, вы ошиблись. В объектной модели вообще нет возможности получить срез по неполному набору измерений.

отбор = новый структура(); отбор.Вставить("Номенклатура",справочники.номенклатура.НайтиПоКоду("07997 ")); рт = регистрысведений.ЦеныНоменклатурыКонтрагентов.СрезПервых(дата("20061111"),отбор);

Прекрасно нашел первую запись по данной номенклатуре после 2006 года 11 ноября

работает судя по описанию синтаксис помощника начиная с версии платформы 8.0, а это уже точно больше 10 лет

Вы неверно поняли суть. Перечитайте статью, она короткая.

Как получить:

01.08.2021, Ложка, 190 р.

01.08.2021, Вилка, 155 р.

01.08.2021, Ложка, 191 р.

из:

01.01.2019, ООО Ромашка, Ложка, 150 р.

01.02.2019, ООО Ромашка, Вилка, 120 р.

01.03.2019, ООО Ромашка, Вилка, 125 р.

01.02.2020, ООО Незабудка, Ложка, 165 р.

01.03.2020, ООО Незабудка, Ложка, 167 р.

01.08.2021, ООО Василек, Ложка, 190 р.

01.08.2021, ООО Василек, Вилка, 155 р.

01.08.2021, ООО Одуванчик, Ложка, 191 р.

?

И мне тоже сложно понять суть статьи.
У регистров сведений «глупее» виртуальная таблица — она не умеет дополнительную группировку делать (они вообще глупее и ближе к чистому SQL относительно других объектов). А виртуальная таблица регистров накопления, например — группировать умеет.
Поэтому, короткий ответ: группировать «вручную», т.е. в запросе.

Дальше длинный ответ.
Там, где в регистре сведений есть дополнительные измерения — они обычно нужны для бизнес логики. В вашем случае это очень похоже на цены поставщиков. Выкинуть оттуда измерение поставщика можно, но как вам это нужно сделать в каждом конкретном случае — это очень ситуативно, поэтому разработчик и думает об этом в каждом случае. (может вы среднюю цену захотите между поставщиками, может макс/мин, а может будете оценивать объем закупок и взвешенную среднюю делать).

Давайте я вам обратный пример приведу. Вы выбросили измерение поставщик и использовали эти данные в аналитике за год для финансиста: например, себестоимость ложки. Финансист смотрит на цифры и видит, что в они от месяца к месяцу делают +20%, -20%, +20%, -20%. Финансист делает вывод покупать ложки только в четные месяцы и ошибается. Потому что в реальности это были прайсы от 2х поставщиков. У одного из них цены на 20% ниже другого, один поставщик повышает цены только по четным месяцам, а другой по нечетным. В реальности ложки можно было покупать всегда у поставщика с более дешевой ценой.

Тупой ответ на вопрос: "Как получить:01.08.2021, Ложка, 190 р. ...."

Вот так:

ВЫБРАТЬ
	Ц.Период КАК Период,
	Ц.Товары КАК Товары,
	Ц.Поставщик КАК Поставщик,
	Ц.Цена КАК Цена
ИЗ
	(ВЫБРАТЬ
		МАКСИМУМ(Ц.Период) КАК Период,
		Ц.Товары КАК Товары
	ИЗ
		РегистрСведений.Цены.СрезПоследних КАК Ц
	
	СГРУППИРОВАТЬ ПО
		Ц.Товары) КАК т
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.Цены КАК Ц
		ПО т.Период = Ц.Период
			И т.Товары = Ц.Товары

Развернутый ответ: а что выхотите получить?

Если "все цены по каждой номенклатуре на последнюю дату, когда такая цена есть", то использование среза последних, игнорируя описание этого механизма - так себе затея.

Смотрите выше про молоток.

Я хочу получать последние записи. И я не хочу получать бессмыслицу в результате запроса.

ответ срез последних по дате, это стандартный функционал регистра сведений в вашем случае это дата 01.08.2021

Так было бы, если бы 1С сделала срез правильно. Но сейчас запрос вернет и 19 и 20 и 21 год как последние записи. В этом и проблема

Автор статьи не хочет принять логику 1С и настаивает на своём велосипеде с квадратными колесами. Ну пусть так.

Там нет никакой логики, а есть просто небрежность.

Конечно же я все внимательно слушаю. Более того, я подробно отвечаю на объяснения и показываю, чем они меня не устраивают. Иначе бы та ветка не была бы такой длинной.

Почитал ветку. Миша там, конечно, расписался в своей некомпетентности как 1Сник.

Потому что "много людей"? У вас другие аргументы есть?

Вам приводили аргументы не раз. Тысячи 1с программистов понимают как работают регистры, и всех все устраивает, ни у кого ошибок нет. Кроме вас.. видимо дело все таки не в платформе?

Вот и вы приведите еще раз. А пока вы этого не сделали, вы просто воздух сотрясаете

А смысл их приводить если вы не хотите их принимать. Вы что-то там себе придумали оторванное от реальности, и с пеной у рта это доказываете

Дальнейшую дискуссию считаю бессмысленной. Удачи в войне с регистрами сведений

Что значит - не хочу принимать? Так прям и говорю: не принимаю ваше доказательство, потому что оно ваше? Или, все-таки, подробно разбираю его противоречивость и несостоятельность? Приведите состоятельное (ну или хотя бы непротиворечивое) доказательство вашей позиции и я его приму

Ниже вам ответил по вашему кейсу, и не только я, где расписал по тексту запроса. Как в РС и как в РН было бы. Вы же начали писать про суммы и максимумы, однако своё фиаско не видите в упор.

На мой взгляд в статье только одна ошибка - её название. Куда правильнее было бы использовать: "Нет времени понимать - тисни статейку" или "Как опозориться на Хабре на 2 минуты".

Пролог. [Периодические] регистры сведений явились продолжением и улучшением периодических же справочников из версии 7, и являются гораздо более продуманной конструкцией. "Автор с двадцатилетним стажем" об этом не знает либо, что вероятнее, сознательно упускает, дабы не рушить свою же "Теорию Непонимания".

Действие. Придумав не имеющую практического смысла задачу, пытается разоблачать механизмы, принцип действия которых не понимает. Не могу представить, зачем мне вдруг понадобится последняя-распоследняя цена товара без привязки к поставщику? Это как заявить: "Везде товар продается по 100 рублей, а в одном магазине - за 50. Но в каком - не скажу". Т.е. цена сама по себе (без полного набора измерений) не имеет смысла. Косвенно автор сам себя же и обличает парой абзацев выше, описывая модель связей.

Техническая часть. СрезПоследних() возвращает виртуальную таблицу, из которой затем выбираются данные. Что характерно, автор даже привел цитату из документации, но сути все равно не понял.

Предназначена для получения наиболее поздних записей регистра сведений на указанную дату (включительно). Включает только активные записи. По каждой комбинации измерений будет найдена наиболее поздняя запись, но не более поздняя, чем указанная дата.

При "неполном наборе" из примера это произойдет следующим образом:

  1. Устанавливается отбор по товару: только Ложки и Вилки (выделены красным);

  2. В виртуальную таблицу попадут только строки с максимальной датой (зеленые);

  3. Автор выбирает из виртуальной таблицы только поля "Товар" и "Цена";

  4. УДИВЛЕНИЕ???

Эпилог. В одной из серий "Симпсонов" есть диалог:

  • Кто умеет - делает. Кто не умеет..?

  • Учит?

  • Нет, идет домой! Как можно учить, если не умеешь?!

Smoke on the Daughter
P.P.S.

Видимо, двадцатилетний опыт не позволил автору должным образом оформить статью, поместив данные в таблицы для упрощения чтения.

Получение последней цены товара из регистра сведений, где есть два измерения - это реальный кейс. Для наглядности. Вот исходные данные:

01.01.1990, ООО Ромашка, Ложка, 3 руб.

01.01.2021, ООО Василек, Ложка, 120 руб.

01.02.2021, ООО Василек, Ложка, 122 руб.

Так вот. Я хочу в результате запроса к срезу ПОСЛЕДНИХ получить:

01.02.2021, Ложка, 122 руб.

И я не хочу получать:

01.01.1990, Ложка, 3 руб.

01.02.2021, Ложка, 122 руб.

Потому что запись от 1990 года не относится к категории ПОСЛЕДНИХ. Это - просто ненужное старье

Может быть вам наложить условия на все измерения регистра? Если не нужен Поставщик, проектируйте другой регистр который будет вас устраивать

Во-первых, реальный кейс, который побудил меня написать статью, был на типовой конфигурации. А менять типовую конфигурацию ради одного отчета неразумно.

Во-вторых, если у вас два измерения, тогда вам надо будет создать три регистра, чтобы покрыть все возможные случаи. Если три измерения, тогда регистров будет шесть. А для четырех измерений потребуется уже 13 регистров. Вы уверены, что это правильный путь, вместо того чтобы убрать всего лишь одно (2,3) лишнее поле из группировки?

Странный кейс. Получается вы хотите найти последнюю цену по которой покупали товар не важно у какого поставщика? Группируйте по дате в запросе для отчета. Чем вам РС не угодили - не понятно

Или просто по-другому написать запрос, например сгруппировать срез последних и не надо делать 13 регистров.

Группировка среза последних не решит проблему.

Хорошо, возьми сначала срез по всем поставщикам, сложи во временную табличку и вторым запросом найди различные номенклатуры и максимальный период. Т.е. получи как-бы срез последних, но от своей таблички уже, т.е. как его сама платформа от регистра получает. Запрос у тебя немного удлинится да, но регистров кучу лишних тебе делать не надо. Либо я чего-то не понимаю, что требуется, мне кажется для этой задачи получить последнюю цену ложки независимо от контрагентов - норм.

Зачем делать срез последних от среза последних, если можно сразу сделать нормальный срез?

ну сделайте нормальный срез, кто ж против, я просто предложил как идею, чтоб не делать кучу регистров, обойтись запросами. Любая идея, кроме кучи регистров из всех сочетаний будет лучше, кажется.

Если рассуждать с точки зрения предметной области - то вопрос "какие последние цены на ложжку у всех поставщиков" с ответом - у ромашки - такая, у лютика - такая - смысл имеет. Также имеет смысл вопрос "какие цены у поставщика "лютик"". А вопрос "получи мне самую последнюю цену на ложку, не важно от какого поставщика" - встречается намного реже (мне не встречался ) ). Автор! найди более приближенный к реальности пример.

А вообще заметил, что на РС за последние недели что-то полезли претензии - и на мисте и на партнерском форуме. Такое ощущение, что где-то появилась "вкусная" вакансия, где на вопросах по РС валят )

Единственное, что я бы поменял на месте 1с - это запретил бы в параметрах виртуальной таблицы периодического РС использовать не измерения.

Пожалуйста. Вот вам другой пример. Заказчик говорит иногда мне будут нужны последние документы продажи по контрагенту, иногда последние документы продажи по складу, а иногда последние документы продажи по сочетанию склад+контрагент. И что в этом случае следует делать? Создавать три регистра?

Как к этой задаче относятся регистры сведений?

Зачем запрещать? Надо уметь пользоваться правильно

Например по условию в параметры Цена<42 можно получить данные когда ложка стоила меньше 42 рублей

З. Ы. Я бы добавил в виртуальную таблицу дату конца действия периода

Не, тему то автор нужную поднял, например нам надо найти как раз самую дешевую ложку и когда ее покупали, чтоб знать не обманывают ли нас другие поставщики, не задирают ли цену. Но просто это можно и по-другому, кажется, обойти, не плодить регистры на все случаи жизни для всех комбинаций, а обойтись одним и тем же регистром.

Ну и как быть, если в один момент времени по разным комбинациям измерений есть значения? с РН действие понятно - суммировать. С РС что? Напомню, что в ресурсах могут быть нечисловые данные. Вот эту неопределенность и "разрешили", отказавшись от группировки по невыбранным измерениям и переложив ответственность на прикладного программиста, который сам уже может с этим сделать, что ему нужно в конкретном случае предметной области - минимум, максимум, количество различных или набор значений.

А программисту не нужен ни минимум, ни максимум. Программисту нужен срез последних. И его можно было сразу сделать нормальным. Просто правильно написав GROUP BY

Покажи мне пример правильного group by, если в один момент времени у двух поставщиков по одной позиции установлена разная цена. Структура регистра - два измерения, номенклатура и поставщик, ресурс - цена. Периодичность - день. Причем правильный прям для всех случаев, чтобы это стало новой механикой работы виртуальной таблицы. И для случая нечисловых ресурсов тоже.

В таком случае, если в исходном запросе стоит только Номенклатура, то и GROUP BY должен быть только по Номенклатуре. Вообще техническая сторона дела примитивна. Что поставишь в GROUP BY, по такому набору измерений и получишь срез. Поставишь Номенклатура, Поставщик, получишь срез по Номенклатура+Поставщик. Поставишь только Номенклатура, получишь срез по Номенклатура.

Кроме group by <список измерений> ты же хочешь получить какое-то значение в ресурсе? какое конкретно? Причем сделать так, чтобы всех устроила такая работа виртуальной таблицы.

Последнее же. В чем вопрос? Начинаю догадываться, что вы просто не в теме

Какое последнее, если один период, по выбираемым измерениям одно значение, а по пропускаемым измерениям есть разные значения?

01.07.2022; поставщик 1;ложка;10.00;

01.07.2022; поставщик 2;ложка;11.00;

Для запроса

Выбрать Номенклатура, Цена Из РегистрСведений.ЦеныПоставщиков.СрезПосделних

что должно получиться? Какое из них "последнее"? Какая группировка "правильная" для того, чтобы зафиксировать её в качестве механики работы виртуальной таблицы?

Начинаю догадываться, что вы просто не в теме

Ну-ну

Вы когда-нибудь делали срез последних? Группировка + соединение с и исходной таблицей?

Еще раз. что выведет 1сный срез? две строки с разными ценами. Что предлагаешь вывести ты для этих данных?

Это прям не соответствует тому, что ты писал выше: что пропущенные измерения должны схлопнуться в одну строку.

Выше я писал, что надо выдавать последние записи, потому что виртуальная таблица называется "Срез последних". Если последних записей больше одной, тогда можно выдавать больше одной

Об этом я здесь уже писал. В идеале иметь уникальную дату. В реальном мире никакие два события не происходят в точности одновременно. Если это невозможно, тогда можно выдавать в результате несколько записей

В реальном мире у разных поставщиков с 01.07 вполне могут начать действовать новые цены. А еще в регистре сведений в реальном мире ресурсом кроме цены может быть что-нибудь нечисловое, например "статус" - "в наличии; под заказ; что-то ещё"

Но какая-то одна из этих двух цен более "последняя", чем другая. В реальном мире. Но не суть, пусть в результате будут две цены

Но не суть, пусть в результате будут две цены

Ну вот в 1сной виртуальной таблице и будет две цены.

В 1С-ной таблице будет две записи при:

01.07.2022; поставщик 1;ложка;10.00;

01.07.2022; поставщик 2;ложка;11.00;

и при:

01.07.2000; поставщик 1;ложка;10.00;

01.07.2022; поставщик 2;ложка;11.00;

А при:

01.07.2000; поставщик 1;ложка;10.00;

01.07.2001; поставщик 2;ложка;11.00;

01.07.2002; поставщик 3;ложка;12.00;

01.07.2003; поставщик 4;ложка;12.00;

01.07.2004; поставщик 5;ложка;13.00;

01.07.2022; поставщик 6;ложка;14.00;

будет 6 записей в результате, хотя нам нужна всего одна

Конечно можно обойтись одним регистром, если делать нормальный срез. И не пользоваться ненормальным 1С-овским

А какой срез "нормальный"? В какой платформе/системе работает так, как вам нужно?

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

Нормальный срез - это срез с нормальным GROUP BY. Таким, в котором присутствуют только те поля, которые заданы в исходном запросе

В любом случае согласитесь, лучше написать немного по-другому, чуть сложнее запрос, сделать в нем нужную группировку, для своей конкретной задачи, чем плодить кучу регистров лишних для всех комбинаций срезов, и загромождать этим БД.

Тут есть голоса как за подход 1С, так и против...

Немного ретро из собственного опыта, откуда есть пошло моё э-э-э, настороженное отношение к программерам 1С.

28 лет назад, в эпоху DOS 5.01/6.22, сетевых адаптеров IOLAnet10/25 (коаксиальные кабели, г. Обнинск) и диковинных (тогда) сетей на не коаксиальных кабелях, я выиграл конкурс (у 1С в т.ч.) на разработку сетевой базы данных для БТИ большого южного города. Потом все домовладения города, (уже тогда) почти миллионника, на этой базе/программе прошли приватизацию, и более 13 лет её сопровождал/модернизировал. Но суть не в этом - основная проблема программеров 1С заключалась в том, что все доступные базы (.dbf, Clipper) они открывали сразу и закрывали только по завершению проги. Это сильно "раздувало" параметры файла Config.sys каждого компа в сети, а на сервер, в условиях ограничений тогдашней работы с памятью, возлагало непосильную ношу при любых её количествах. И уж конечно они не заморачивались ассемблерными вставками, подменой символов и прочим для улучшения юзабилити и экономии памяти.

Мой подход (открываем только нужное сейчас и не забываем закрывать) не требовал вообще трогать файл Config.sys (использовались значения по умолчанию, files=25, кажется) и до 40+ компов работали в сети под DOS, что в те времена (1996...2000) было ого. С тех пор (не только у 1С) наблюдаю повсеместное... нежелание программеров заморачиваться, и так сойдёт. А как нет - покупайте современную технику. Это было так, когда 1С ещё совсем не был монополистом (да, так было!), а уж теперь, когда подмял под себя всё и всех - диктует волю потребителям. А надо бы - программерам регулярно "хвосты крутить", или, как у некоторых капиталистов, децимацию учинять, конкурсы и т.п., избавляясь от себя не уважающих.

Цитируем статью в Википедии: „14 августа 2002 года выпущена «1С:Предприятие 8.0 ознакомительная версия»“

19 лет Снеговику уже на днях стукнуло!

О чём, собственно, спорить то?

Суть спора - документация 1С по работе среза последних может быть понята неоднозначно, как, собственно, и произошло с автором.

Не совсем так. Как они должны исправить документацию? Не делайте запрос по неполному набору измерений, потому что получите бессмысленный набор данных? И это при том, что переделать на правильный срез займет примерно столько же времени, что и переписывание документации

Да, должны были явно написать, что срез последних имеет смысл только для всех измерений, а не подразумевать, что все разработчики это поймут сами. А не переделывают срез видимо потому, что нет такого запроса от значительного числа пользователей, только и всего. Это очень частный случай, когда реально нужен срез последних не по всем измерениям.

Ну подумайте сами. Смысл писать? Кто-то все равно будет введен в заблуждение, думая что механизм работает, как в РН. Надо не просто документацию исправлять, надо переделывать, вызывать сообщение об ошибке при выборе неполного набора измерений. А это, в свою очередь порождает вопрос: а не проще ли группировать правильно?

Если этих кого-то доли процентов, для 1С это не критично. Не нравится 1С - не пользуйтесь 1С.

Вы полагаете, что тех, кого что-то не устраивает в 1С, доли процентов?

Я полагаю, что число тех, кто не сможет разобраться с работой среза последних, после предложенного мной изменения документации, составит доли процентов. Не надо передергивать, Михаил.

Отвечу сразу всем, у меня нет возможности вести дискуссию в комментариях, поэтому я пообщался с автором в привате.
Докладываю, автор всё понимает, его позиция заключается в: «я придумал как было бы классно, а 1с идиоты».
С документацией 1С всё в порядке, там и близко нет никаких указаний полей среза. Читаем по языку запросов:
в конфигурации предусмотрены частотные запросы к срезам последних на текущий момент времени и/или к срезам первых для получения актуальных данных (т.е. когда не задан период в параметрах виртуальных таблиц СрезПервых и СрезПоследних);

при этом остальные условия для виртуальных таблиц СрезПервых и СрезПоследних задаются только на значения измерений

Условия я выделил жирным специально. Вот как выглядит обращение к срезу по справке:
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(Дата, Истина)

Либо так:
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(Дата, Истина AND Измерение = &Переменная)


Для тех кто не знает 1С, это калька с SQL блока where true and table.Измерение = &Значение, то есть фильтр будет идти по значению в поле.

Автор напрочь игнорирует, описание того, что это условие, ему похер на логические операнды, на аналогию с группировкой и блоком where. Для него, раз там есть отсылка к измерениям, значит он тут указывает по каким полям срез...! И хоть кол на голове ему чеши, 4 сообщения про одно и то же, тупо проигнорированы и аргументы его, не меняются.
Далее смотрим объектную модель (цитата из справки):
СрезПоследних (<Конец периода>, <Отбор>)

Ему опять же — глубоко насрать на то, что параметр называется отбор, раз он отбор осуществляет по значениям измерений, то вынь и положь ему срез по ним, а не срез, который был сконфигурирован, при создании регистра. И в жопу, составной кластерный индекс, по котрому и происходит группировка, в жопу итоги, которые были предрасчитаны…
Срез последних, это очень ресурсоёмкая операция, и когда делались регистры, то он делался именно для ускорения работы, поэтому для этого фиксируются измерения, создаются под них индексы, создаются итоги, и удобный доступ ко всему этому. С регистром, вы работаете без всяких срезов, а если нужно, то — ускоряетесь с помощью этого механизма.
А задач, где может потребоваться нестандартный срез, под которые не подходит данный 1с функционал — море. Например, очень часто, записи из регистра не удаляются, а помечаются как недействительные (не обязательно параметром булево) и должны быть вырезаны ДО среза, так как не являются результатом, а просто должны игнорироваться, или данные должны быть заранее отфильтрованы по другим критериям, или срез делается не по конфигурации регистра, а по своим полям, пусть даже ресурсным. Всё это легко и непринуждённо делается обычным запросом. Но нет — автору вынь да положь, накликивание того, что хочет именно он, в данный момент!
И ещё раз, конфигурация среза создаётся при создании регистра заданием полей, которые называются измерениями, потом вы просто с ним работаете. Если вы сделали 3 измерения, а почти всегда используете 2, то это архитектурный просчёт, если вам в редких случаях надо использовать 2, то вы не сможете использовать механизм ускорения в виде среза 1С, а просто используете обычный доступ к регистру и делаете через вложенный запрос кастомный срез в ручную.

Вы сами себя прочтите медленно и внимательно.

С документацией у 1С все в порядке. Там про этот случай ничего не написано (!) Ну ха-ха же, нет?

Из нас двоих вы гораздо более "упертый". Я не делаю ОТБОР. В диалоге два раза сказал об этом. Давайте здесь еще раз повторю. Я не делаю ОТБОР.

Что касается индексов и производительности. Ну допустим, разработчики все предусмотрели и сделали быструю операцию для полного набора измерений. Для неполного набора быстрая операция невозможна. Ну и? Дальше-то что? Что с этим делать? Запрещать операцию? Делать хоть и медленную, но правильную? Ответ разработчиков 1С - а пусть будет неправильно, зато быстро. Это по-вашему разумно?

Вам уже писали, но повторюсь, что делать если цены зарегистрированы на один товар в один день от нескольких поставщиков? Что должен выдать ваш запрос?

Несколько строк с ценами

Максимальную цену

Минимальную цену

Среднее арифметическое

Среднее геометрическое

Цену поставщика с большим приоритетом

Ещё какая-то логика

В статье подробно об этом написал.

В идеале у вас должна быть обеспечена уникальность значений типа дата хотя бы в рамках информационной базы. Это соответствует тому, что мы имеем в реальном мире.

Если уникальность дат не обеспечена, тогда запрос будет возвращать несколько строк. Но это должны быть последние цены, а не как сейчас - тоже несколько строк, но не последние, а все подряд

какое бизнес решение вы хотите принять на основе этой информации? если речь про неактуальные цены поставщиков то можно наложить условие вида период "больше какая-то дата актуальности". А с ценами от поставщиков, установленными в один день, хоть и в разные секунды что делать? Реально пример плохой же. А хорошего - нет.

Ничего не делать. Бери любую, любая годится

Кто за эту уникальность отвечать будет? Привезли товар одного поставщика, потом другого в один день. Ввели положим в порядке хронологии, только кому она нужна эта хронология? Если анализ проводится с точностью до дня?

Пример какой-то умозрительный. Может в данном случае входящую прямую себестоимость за единицу оценивать?

Платформа и будет отвечать. Добавляешь к дате четыре байта и инкрементируешь

То есть воля случая? Зачем такой учет?

Нормально. Если ты хочешь впихнуть в одну секунду миллион документов, а система сама заботится о том, чтобы они встали в некотором порядке. Почему нет? Если тебе важен порядок, тогда сам его задаешь. Тут нет никаких проблем

Уникальность дат в РС обеспечена платформой в разрезе измерений регистра

Только до того момента, когда вы попытаетесь выполнить запрос по неполному набору измерений. Тут-то эта уникальность и пропадает с концами

Вам уже очень много людей тут и на мисте объяснило - РС так НЕ работает! И не должен! Вы либо принимаете правила, либо пишите свою платформу. Если вы за всю вашу практику с регистрами сведений работать не научились, то я сомневаюсь в вашей квалификации. Ваша же задача легко решается в конструкторе запроса.

Регистр сведений должен работать правильно. Вы понимаете разницу между не работает и работает не правильно?

Да, я в результате решаю задачу другим путем. Но я потратил время. А также у меня был риск сдать работу заказчику с ошибкой, потому что у разработчиков с логикой проблемы, а документация вводит в заблуждение

  1. Регистры сведений работают правильно и решают свою задачу на 100%, просто вы это не хотите понять.

  2. Чтобы не сдавать заказчику работу с ошибками - нужно перед этим тестировать то, что вы написали.

Срез последних не выдает последние записи. И это не обставлено сообщением об ошибке и не описано в документации. Вы просто получаете неверный результат. Если хотите опровергнуть - аргументируйте, пожалуйста

Есть ошибки разной степени "опасности". Те, которые вы с высокой долей вероятности увидите сразу не опасны. Но есть и такие, которые могут "проскользнуть". Ошибка, которую провоцируют разработчики, как раз очень опасная. В моем кейсе элементарно можно было получить на реальных данных картинку неотличимую от нормальной работы среза последних. И только потом когда-нибудь получить претензию от клиента

Вы не обижайтесь, но доказывать вам что регистры работают так как должны работать,, все равно что антипрививочникам доказывать про пользу прививок. Как об стенку горох. Попроситесь на платную консультацию к Чистову или Гилеву

К Чистову? Спасибо, я пока подожду

Не надо аналогий. Давайте аргументы

В книге Практическое пособие разработчика 1С найдёте аргументы.

Вы же не хотите пользоваться инструментами так как они работают (так как ими пользуются все).

Е мое! Сорри, за миром 1С не слежу в последнее время... Очень жаль

И еще, вы не путайте платформу и то как разработчики сконфигурировали решение. Если они сконфигурировали регистр сведений с двумя измерениями - значит подразумевался отбор по двум и только по двум измерениям, иначе получится белиберда.

А почему бы не сделать платформу так, чтобы белиберда не получалась?

Тема интересная. Надеюсь когда-нибудь поподробнее узнать ход мыслей и резоны разработчиков платформы непосредственно от действующих лиц, хотя многое уже сейчас можно почерпнуть из двухтомника по платформе. А домыслы, приведенные в статье, мне кажутся очень поверхностными или просто неверными.

Начиная с того, что такое документ и регистр.

По моему пониманию, в базе данных 1С хранится модель (упрощенное представление) контролируемой (управляемой) системы. Непрерывно-дискретного типа. Время - дискретно (продолжительность событий несущественна), параметры состояния системы - непрерывны (выражаются, в основном, вещественными числами).

Тогда документ необходим для фиксации событий (мгновенного изменения состояния) системы. Время документа - момент события. Его реквизиты - "обстоятельства" события.

Собственно состояние фиксируется в регистрах. При проведении документа. Тут имеет место денормализация, которая делается намеренно. Потому, что события могут быть разнородными. Регистр - это "общий знаменатель" - хранилище результата разнородных событий.

Регистры накопления и регистры сведений с этой точки зрения различаются мало. В одних (накопления) фиксируется величина изменения параметра. В других (сведений) - фиксируется значение параметра после изменения.

Выбор делается исходя из того есть ли в реальности возможность зафиксировать все изменения или нет. Контролируется ли граница? В бассейне (на огороженном складе) можно поставить датчики прихода и расхода. Используем регистр накопления. В озере (на производстве) фиксируем уровень воды (инвентаризируем остатки незавершенного производства) - используем регистр сведений. Что удобнее или эффективнее, если удается посчитать, на усмотрение модельера. Есть и взаимно-однозначное преобразование.

Встроенная группировка по измерениям (время в этом утверждении не измерение!) в регистре накопления, как мне кажется, это всего лишь дополнительная (и не всегда бесплатная по времени вычислений) опция. Которая не всегда имеет смысл (апельсины с бочками, штуки с килограммами и прочее).

Для регистров сведений эта группировка имеет смысл еще реже. Вот ее и не сделали. Из экономии, чтобы зря не считать то, что редко кому нужно и зря не выбрасывать из результата запроса нужные данные.

Если представить данные регистра сведений как экран многоканального осциллографа, то срез последних (состояние на заданный момент) вернет логичное количество строк, даже при пропущенном измерении "поставщик" в запросе.

Как в дизайне регистров сведений нарушается теория баз данных я тоже не понял. Прочитал еще раз главу 23 Дейта (про хронологические базы данных). Вроде бы все по канонам (полу-хронологическое представление).

Конечно, изначально стройная концепция справочники-документы-регистры разработчиками прикладных решений часто вынужденно размывается, но это совсем другой разговор. Не про велосипед, а про более сложные вещи.

Что вы называете домыслами? Конкретно?

Что я допускаю, что разработчики не были знакомы с теорией баз данных?

Или что они как дети малые бросили все как есть, вместо того чтобы доделать?

Первое, согласен, домысел. А вот второе - это факт данный нам в ощущениях.

У вас странная логика. Если операция 237065122+486369458 встречается довольно редко (а ведь так оно и есть), то нет ничего страшного в том, что результат не 723434580, а 876222544.

Стараюсь вас понять...

Кажется, назвав таблицу с датой документом, вы упростили себе понимание и объяснение понятие документа другим людям. А затем уже зафиксировали это в голове и не стали переосмысливать. Суть понятия "документ" от этого потерялась. И то, зачем, кроме документа, еще и регистр сведений, тоже.

Далее, в названии "регистр накопления" слово "накопление" вы поняли буквально. Считая, что накопление идет по измерениям. А оно относится только ко времени. Если группировки по измерениям не будет или оно будет выполняться другим агрегатом, от этого регистр не перестанет быть регистром накопления. Это обычный "интегратор" - деталь многих систем управления.

Далее, результат запроса к виртуальному регистру "срез последних" вы смешали с собственно со способом представления виртуального регистра в базе данных, который можно материализовать и который должен соответствовать ограничениям. От этого вопросы про теорию баз данных.

Смотрите. Есть виртуальная таблица. Называется "Срез последних". В соответствии с названием, мы ожидаем, что она вернет последние записи. И это, и только это, надо считать правильной работой. Однако, оказывается, что если вы укажете в запросе неполный набор измерений, вы получите в результате не последние записи. Вы не получите сообщение об ошибке. Вам не скажут: "Ей, парень, это так не работает! Нужен полный набор измерений". Вам просто выдается неправильный результат. Документация написана так, что можно понять, как угодно. Лично меня это задевает еще и потому, что я прекрасно представляю, как это устроено внутри. Вы все равно так или иначе транслируете исходный запрос в SQL запрос. И вы все равно формируете список полей для группировки. Сделать так, чтобы в список для группировки попадало только то, что есть в исходном запросе - это вопрос одного "если". Проще может быть только замена значения константы. И да, меня злит то, что разработчики нашли время на никому не нужный срез первых и не нашли время на это "если". И еще, я, так же, как вы, пытаюсь понять - что движет теми, кто пытается любыми способами защитить разработчиков, даже в такой очевидной ситуации

"...в соответствии с названием, мы ожидаем..."

Мне кажется, имеет место семантическое когнитивное искажение. Оно заключается в тенденции полагать, что знаешь значение слова, хотя на самом деле знаешь лишь область его применения и употребления.

"Срез последних".

Во-первых, последних из чего? Вы, наверное, думаете: записей? - А я думаю: значений. - Ведь 1С имеет, в первую очередь, дело с понятиями предметной области, а не баз данных. Эти абстракции (баз данных) должны быть скрыты, а не торчать снаружи.

"Срез последних значений". Смысл несколько меняется. - Не находите?

Надеюсь, слово "последние" мы понимаем одинаково.

А вот слово "срез"? Вы, наверное, считаете: "отрезанный кусок". - Но тогда лучше было бы "набор" (часто встречается в документации, не добавляет лишних сущностей). А я считаю: состояние в определённый момент развития, движения. Ну, или "Место, по которому что-л. срезано; // Круто обрывающаяся поверхность с обнажившимися пластами почвы, горной породы".

В общем, читай медленно, пиши быстро, как говорит пример классика русского языка.

Не знаю, убедили ли вас эти лингвистические экзерсисы, но они хотя бы должны вам показать, что ситуация не такая очевидная, если не показали, что она очевидно не такая.

Ну и, кстати, в данном случае, лично я защищаю не разработчиков, а свое понимание работы этого механизма.

Хоть записей, хоть значений. Выше я уже приводил пример

01.02.2021, Ложка, 122 руб.

Это последние записи

01.01.1990, Ложка, 3 руб.

01.02.2021, Ложка, 122 руб.

А это - не последние записи. Разве не очевидно?

Вот именно что это именно последние записи в срезе набора измерений. Это именно так работает, дядь. Потому что данный конкретный регистр сделан так что должен хранить закупочную цену по каждому поставщику. Хочешь другой учёт - допиливай, это уже писалось выше.

Не надо использовать слово "сделан" там, где должно быть слово "не доделан". Результат, который сейчас выдается лишен всякого смысла

Может вам проспаться?

Результат, лишенный смысла, выдаётся в результате того алгоритма который написали вы.

Аргументируйте. Чем результат

01.01.1990, Ложка, 3 руб.

01.02.2021, Ложка, 122 руб.

лучше

01.02.2021, Ложка, 122 руб.

Где и как он может быть использован?

Текст запроса и структуру регистра в студию

В статье кейс подробно описан, но мне не лень повторить.

Регистр (из типовой УТ) с измерениями Товар,Поставщик и ресурсом Цена.

Запрос

ВЫБРАТЬ Период,Товар,Цена ИЗ РегистрыСведений.ххх.СрезПоследних

В документации:

"Предназначена для получения наиболее поздних записей регистра сведений на указанную дату (включительно). Включает только активные записи. По каждой комбинации измерений будет найдена наиболее поздняя запись, но не более поздняя, чем указанная дата."

Я в полной уверенности, что агрегирование пройдет по тем полям, что указаны в запросе. Так же, как это работает в РН

Запрос

ВЫБРАТЬ Период, Товар, Поставщик, Цена ИЗ РегистрыСведений.ххх.СрезПоследних

вернет вам корректную выборку

01.01.1990, Ложка, Поставщик1, 3 руб.

01.02.2021, Ложка, Поставщик2, 122 руб.

Потому что платформа возвращает последнее значение по НАБОРУ измерений в данном случае Товар + Поставщик.

Потому что цену вы храните и по товару и по поставщику.

"Предназначена для получения наиболее поздних записей регистра сведений на указанную дату (включительно). Включает только активные записи. По каждой комбинации измерений будет найдена наиболее поздняя запись, но не более поздняя, чем указанная дата."

В данном случае имеется ввиду комбинация значений набора измерений, а не каждого измерения по отдельности.

Товар1 + Поставщик1

Товар2 + Поставщик1

Товар1 + Поставщик2

Товар2 + Поставщик2

"Я в полной уверенности, что агрегирование пройдет по тем полям, что указаны в запросе. Так же, как это работает в РН"

Вот именно что это работает не так же как РН! Потому что в РН ресурс - всегда число! (это вам уже говорили), а в РС в ресурс вы можете указать хоть число, хоть строку, хоть ссылку. Как вы собрались агрегировать нечисловые данные?

Уже немножко зевая.

И там и там АГРЕГАТНАЯ функция. Только в РН это СУММА(), а в РС это МАКСИМУМ().

Если ресурс не число, ты делаешь допустим Макс(Период) то у тебя не будет 1 строки в результате.

Вот тут. Вы сами на все аргументы отвечаете не по существу. Потому что ответить вам нечего по факту. Все остальные ваши замысли и догадки - бред.

То что вы не научились правильно интерпретировать документацию и спустя время практики не научились работать с основными механизмами платформы - ваша проблема, а не платформы

Что значит - не по существу? Вы выдвигаете аргумент, что предлагаемая мной схема иногда будет возвращать дубли. Я задаю резонный вопрос: а 1С разве не возвращает сейчас дубли? Что может быть более "по существу"?

Это не дубли, просто вы одно измерение не включили в выборку. Я же говорю - это сугубо проблема в вашем понимании регистров сведений

Если бы было как в РН, то результат был бы НЕ

01.02.2021, Ложка, 122 руб.

цена бы сагрегировалась с

01.01.1990, Ложка, 3 руб.

и получилась бы 125 руб., что есть некорректно

Это не последние записи, но это записи виртуального регистра срез последних "цены поставщиков". В термине срез последних вы забываете слово "срез". А это важно...

Зайдем с другой стороны.

Есть запрос

ВЫБРАТЬ Поставщик, Номенклатура, Цена ИЗ ВТ

И запрос к той же таблице

ВЫБРАТЬ Номенклатура, Цена ИЗ ВТ

Вы наивно ожидаете, что они вернут разное количество записей?

Почему вы ожидаете того же самого от запросов

ВЫБРАТЬ Поставщик, Номенклатура, Цена ИЗ РегистрыСведений.ЦеныПоставщиков.СрезПоследних()

и

ВЫБРАТЬ Номенклатура, Цена ИЗ РегистрыСведений.ЦеныПоставщиков.СрезПоследних()

Срез последних - это состояние дел на сейчас, проекция всех изменений на настоящее время, state of art. Очень полезный виртуальный регистр. С опциональной возможностью материализации. С ходу по последнему запросу могу предложить больше десятка сценариев обработки его результатов: определить максимальную, минимальную, среднюю, медианную цену каждого товара "на сейчас", самый дорогой, дешевый, самый волатильный товар "на данный момент", товар с самой старой, самой молодой, с прошлогодней ценой (если период как в статье еще будет), всякие топы, кластеры, самый распространенный, самый экзотический товар и т.п.

А вы по своей желаемой выхолощенной таблице сможете все это определить? Сколько пользовательских сценариев поддержит это только вашим очам видное решение?

В общем логос в данной риторике пора заканчивать, попробуем пафос:

Есть анекдот: "Шеф, в вашем районе один ненормальный едет навстречу движению! Шеф: Какой один? - Их тут сотни!"

Так вот, вопрос: С каким из героев данного анекдота вы себя ассоциируете?

Вот например, в РН Продажи есть измерения Контрагент, Товар, Склад. И вы особо не задумываясь делаете запросы:

Контрагент+Товар

Товар+Склад

Склад+Контрагент

Нормальная же практика. Разве нет? Какие принципиальные основания не использовать ее в РС?

Потому что это РН. Они накапливают данные. Я уже говорил - почитай книгу по 1С, или на курсы запишись

Если у тебя ресурс будет строка, к примеру

Товар1, поставщик1, десять

Товар1, поставщик2, пять.

Что ты будешь агрегировать?

Вы представляете себе - как получается срез последних?

Очень хорошо. Там есть агрегация?

Вот именно что там ее нет. Вы сами себе противоречите.

Но если вы такой гуру - объясните, как же работает срез последних. Я прочитаю.

Вот именно, что она там есть. Вы лучше не позорьтесь дальше

Пример приведите

Upd: что касаемо ресурсов, по периоду естественно платформа ищет максимум до заданной даты

Как же она это ищет? Гуглом или Яндексом? Или все же с помощью GROUP BY? Не подскажете?

Я смотрю у вас синдром преподавателя. Вы прекрасно знаете что имелось ввиду, и решили прикопаться к словам, потому что где-то в глубине души вы понимаете что не правы, но осознать пока не можете

Не к словам, а к пониманию вопроса. У вас оно близко к нулю

Агрегация + соединение с исходной таблицей. Вот так работает срез последних. Прежде чем спорить, разобрались бы что-ли

Вопрос - а для чего вы тогда демагогию развели если все знаете как работает? Со всех точек зрения регистры работают правильно, кроме вашей. Вас просто в ваши баги носом видимо ткнули и вы решили ответственность переложить на 1С.

С каких со всех? Тут сейчас есть только ваша точка и моя. Только вот вы плохо разбираетесь в вопросе. У вас только троллить хорошо получается

С точек зрения:

  • разработчиков платформы

  • Документации

  • Всех тех кто тут и на мисте вам пытался объяснить что регистры работают правильно

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

Процитирую человека с мисты:

«Вы серьёзно, хреначите 20 лет запросы, с пониманием ниже плинтуса предметной области и никто вам по рукам не дал?»

Что? Прям как написали программу, вот прям ровно так и работает? И ресурс бесконечный? Ничего не рвется, не мнется, не изнашивается? Потрясающе, коллега! Как вам удалось такого добиться?

Вам бригаду скорой мед помощи вызвать? У вас галлюцинации

Ещё раз

«Вы серьёзно, хреначите 20 лет запросы, с пониманием ниже плинтуса предметной области и никто вам по рукам не дал?»

Вы профайлер откыли, прежде, чем это утверждать?

Хотите что-то сказать - говорите. Мы вас с удовольствием послушаем

Вы профайлер открыли, прежде, чем это утверждать?

Говорите - что вы хотите сказать, не стесняйтесь. Срез последних - это агрегация плюс соединение с исходной таблицей. Хотите это опровергнуть - приводите факты

Как тут попросить админов прикрыть тему, надо заканчивать попытки объяснить дальтонику что белое это белое. Я вообще не понимаю как он делает кому-то что-то за деньги с таким понимаем платформы

А все дело в том, что «регистры» уже существовали в предыдущей версии. Такое ощущение, что разработчики восьмерки, отважившись на создание нового класса, ровно на этом месте исчерпали весь запас своей креативности. Новый класс они зачем-то отнесли к семейству «регистров», переименовав тру-регистры в «регистры накопления», а неофитов назвав «регистрами сведений».

Ну вы бы ещё предъявили претензии к тому, что морской лев не родственник льву сухопутному, а морской конёк произошёл не от утонувших кобыл тевтонских рыцарей.

Ситуация, когда API системы или сервиса накладывает ограничения на формат входных данных и при невалидном входе выдаёт не исключение, а невалидный результат (Garbage In — Garbage Out) — повседневная обыденность.

Если сильно мешает — напишите инспекцию к EDT, вы ж программист!

Вот это более интересно. Можете сходу привести похожий пример в других системах? Было бы полезно сравнить. И мне и вам

Ничего не знаю про 1с, но прочитал статью с удовольствием, интересное окно в проблемы того мира получилось.

А комменты очень ярко иллюстрируют, насколько же у 1с токсичное коммьюнити, причём, именно стилем речи, а не сутью - может, автор и не прав, но можно же выразить это без этой неуместной пассивной агрессии

Жизнь у них не легкая, вот они и злятся

Автор просто не слышит. До этого ему писали на другом профильном форуме

Что доказывает факт обсуждения на другом форуме?

Есть аргументы - приводите. Послушаем с огромным удовольствием

Представляете, через какой ад прошли те разработчики 1С, которых собеседовал "достаточно много" автор сей статьи? Искренне сожалею.

создать механизм обеспечивающий уникальность значения типа "Дата" как минимум в рамках информационной базы

Что это значит? Как дата может стать уникальной? Вы наверно путаете дату с моментом времени.

На счет приведенной задачи она не имеет смысла. Если хотите чтобы не было дублей нужно использовать группировку по товару и агрегатную функцию (среднее максимум минимум) на цену, в таком только случае решение получает какой-то смысл. Например в УТ при оприходовании одного того же товара по разным ценам в регистр цены номенклатуры как раз попадает средняя цена.

Sign up to leave a comment.

Articles