Поменяли номенклатурные группы с 1 июля.
Нужно во всех документах заменить старое значение субконто на новое, причём перевыбор номенклатуры не вариант - т.к. перезапрашивает цены.
Можно сделать через групповое изменение реквизитов, собственно что я и сделал по одному конкретному типу документа с отбором.
Собственно вопрос: Как через групповое сделать по всем видам документам замену номенклатурной группы в зависимости от указанной номенклатуры, если учесть что табличная часть может у документа называться "Продукция", а у других "Товары", где-то номенклатура указывается в реквизите "Номенклатурная группа" в табличной части, а где-то в качестве субконто.
Константин Нагибович, пытаюсь осмыслить 1С, но пока не выходит.
Получил список видов документов у которых есть реквизит в табличной части содержащий тип "Номенклатурные группы".
Теперь пытаюсь понять как выбрать непосредственно сами документы, проверить реквизит уже на тип значения и если подходит то поменять.
в соседнем комментарии отписал.
Вроде добрался до реквизита и значения перебором метаданных. Не знаю на сколько правильно.
Для Каждого Док Из Метаданные.Документы Цикл
Если Док.ТабличныеЧасти.Количество() > 0 Тогда
Для Каждого ТЧ из Док.ТабличныеЧасти Цикл
Для Каждого Рек Из ТЧ.Реквизиты Цикл
Если Рек.Тип.СодержитТип(Тип("СправочникСсылка.НоменклатурныеГруппы")) Тогда
//Сообщить(Строка(Док) + " - " + Строка(ТЧ.Имя) + " - " + Строка(Рек.Имя) + " - " + Рек.Тип);
ДокВыборка = Документы[Док.Имя].Выбрать(Дата(2019,04,01), Дата(2019,07,30));
Пока ДокВыборка.Следующий() Цикл
ДокОбъект = ДокВыборка.Ссылка.ПолучитьОбъект();
ТЧОбъект = ДокОбъект[ТЧ.Имя];
Для Каждого Стр Из ТЧОбъект Цикл
Если ТипЗнч(Стр[Рек.Имя]) = Тип("СправочникСсылка.НоменклатурныеГруппы") Тогда
Сообщить("OK");
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Вы же сами ответили на свой вопрос. Делать отдельные прогоны для "Продукция" и "Товары" в вариантах разных названия реквизита. Контролировать результаты с помощью поиска ссылок на объект.
Если умеете программировать, то легче сразу написать обработку, чтобы при перепроведении документов все корректно закрывалось. Закрытие месяца, если там есть распределение затрат, лучше делать после всех замен.
Суммы и счета не меняются, меняются только наименования номенклатурных групп, насколько это сходу видно. По крайне мере у бухгалтерии уточнил (хотя они сами особо не представляют что там ещё может быть).
Так вот. Больше переживаю что какие-то документы упущу и будет каша, которую визуально уже не определишь где и что. Например в отчете продаж по номенклатурным группам, сейчас сразу видно что по конкретная группа даёт продажи в количестве не соответствующим выработке производства.
Поэтому пытался так сделать:
1. Отталкиваясь от субконто - нашёл запросом все субконто соответствующие справочнику "номенклатурные группы", из регистра бухгалтерии ищу все документы регистраторы по этим счетам.
А дальше я не понял как выбрать список конкретных документов, т.к. в запросе "метаданные.документы" не является таблицей.
Да и просто получается упускаю реквизиты табличных частей, которые не являются субконто, что даст разницу в наименовании группы в проводках и в табличной части.
ВЫБРАТЬ
Ссылка
ПОМЕСТИТЬ ВТ_Счета
ИЗ
ПланСчетов.Хозрасчетный.ВидыСубконто
ГДЕ
ВидСубконто В (&ВидСубконто)
СГРУППИРОВАТЬ ПО Ссылка;
ВЫБРАТЬ
РБ.Регистратор
ПОМЕСТИТЬ ВТ_Документы
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК РБ
ГДЕ РБ.Период > ДАТАВРЕМЯ(2019, 04, 01) И
(СчетДт В (ВЫБРАТЬ ССЫЛКА ИЗ ВТ_Счета)
ИЛИ СчетКт В (ВЫБРАТЬ ССЫЛКА ИЗ ВТ_Счета))
СГРУППИРОВАТЬ ПО РБ.Регистратор;
2. Пробую писать обработку, пока не особо успешно, которая будет сканировать все документы из метаданные.документы, проверять наличие табличных частей и по полям искать тип "НоменклатурныеГруппы" и если наименование поля содержит "Субконто", то проверять его тип.
И на найденых полях/субконто производить замену, если рядом в этой же табличной части есть поле "Номенклатура".
Процедура ОбновитьГруппыНоменклатурыНаСервере()
Для Каждого Док Из Метаданные.Документы Цикл
Если Док.ТабличныеЧасти.Количество() > 0 Тогда
Для Каждого ТЧ из Док.ТабличныеЧасти Цикл
Для Каждого Рек Из ТЧ.Реквизиты Цикл
Если Рек.Тип.СодержитТип(Тип("СправочникСсылка.НоменклатурныеГруппы")) Тогда
Сообщить(Строка(Док) + " - " + Строка(ТЧ.Имя) + " - " + Строка(Рек.Имя) + " - " + Рек.Тип);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Тут я получил список видов документов, а как сами то документы получить?
Правильно все понимаю?
Или может есть способ проще чем перебирать все поля всех документов?
ITF, все проще. Закинь ссылку на старую номенклатурную группу в массив и дай на вход функции НайтиПоСсылкам() - на выходе таблица с метаданными и ссылками на объекты, где изменять. Для начала посмотри третью колонку - если видов метаданных мало, то лучше руками пропиши в коде какие реквизиты проверить на соответствие старому значению и требующие замену; иначе, как и планировал, можешь бегать по метаданным. А еще можешь запросом к бухгалтерским оборотам выбрать все регистраторы, которые делают движения со старой номенклатурной группой, а потом исправить и перезаписать их наборы записей.
Дмитрий Кинаш, не уверен что все документы попадают в регистрбухгалтерии, т.к. конфигурация отраслевая на базе 1С Бухгалтерия.
Пока бегаю по метаданным.
Глобальный контекст (Global context)
НайтиПоСсылкам (FindByRef)
Синтаксис:
НайтиПоСсылкам(<СписокСсылок>, <ОбластьПоиска>, <ВключитьОбъекты>, <ИсключитьОбъекты>)
Параметры:
<СписокСсылок> (обязательный)
Тип: Массив.
Массив со списком ссылок на объекты, ссылки на которые нужно найти.
<ОбластьПоиска> (необязательный)
Тип: Массив.
Определяет область поиска объектов. Область устанавливается комбинацией разделителей, в состав которых включены объекты метаданных, среди данных которых следует выполнять поиск.
Элемент массива имеет тип Массив.
Элемент вложенного массива имеет тип:
Объект метаданных – Общий реквизит, разделяющий данные.
Строка – имя общего реквизита, разделяющего данные.
По умолчанию имеет значение Неопределено.
Допустимые значения:
Неопределено,
Массив с комбинациями разделителей, определяющий область поиска,
Пустой массив - область поиска определяется параметрами метода <ВключитьОбъекты> и <ИсключитьОбъекты>.
Примечание. Если комбинация разделителей содержит повторы, то вызывается исключение, т.к. в конфигурации не может быть объектов метаданных, дважды включенных в состав одного разделителя.
Значение по умолчанию: Неопределено.
<ВключитьОбъекты> (необязательный)
Тип: Массив.
Позволяет явно указать объекты метаданных, которые должны присутствовать в области поиска ссылок на объекты.
Элементом массива могут быть:
Объект метаданных.
Строка – полное имя объекта метаданных.
Допустимые значения:
Неопределено,
Пустой массив,
Массив объектов метаданных.
Значение по умолчанию: Неопределено.
<ИсключитьОбъекты> (необязательный)
Тип: Массив.
В качестве элементов массива могут выступать:
Объект метаданных,
Строка – полное имя объекта метаданных.
Свойство позволяет явно указать объекты метаданных, которые следует исключить из области поиска ссылок на объекты.
Допустимые значения:
Неопределено
Пустой массив (нет объектов, которые необходимо дополнительно включить в область поиска).
Массив объектов метаданных.
Значение по умолчанию: Неопределено.
Возвращаемое значение:
Тип: ТаблицаЗначений.
Возвращает ссылки на найденные объекты в виде ТаблицаЗначений.
Первая колонка - исходная ссылка.
Вторая колонка - ссылка на объект, если найденная ссылка соответствует объектной таблице, или значение, олицетворяющее запись необъектной таблицы.
Третья колонка - объект метаданных, которому соответствуют данные, в которых найдена ссылка.
Описание:
Осуществляет поиск ссылок на объекты, переданные в параметре <СписокСсылок>.
Поиск выполняется только в данных, которые доступны в рамках текущего сеанса с учетом разделения (условное разделение также учитывается).
Поиск осуществляется среди всех данных, из которых могут быть ссылки на переданные объекты. Если у пользователя нет доступа к объекту, будет вызвано исключение.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Вызов метода выполняет обращение к серверу.
Примечание:
Если параметр <ОбластьПоиска> не определен или используется режим совместимости конфигурации Версия8_3_4 и ниже, поиск осуществляется во всех тех данных, которые доступны в рамках текущего сеанса с учетом разделения (условное разделение учитывается).
На мобильной платформе параметры <ОбластьПоиска>, <ВключитьОбъекты>, <ИсключитьОбъекты> игнорируются.
Пример:
Ссылки = НайтиПомеченныеНаУдаление();
ТабСсылок = НайтиПоСсылкам(Ссылки);
Для Каждого Ссылка из ТабСсылок Цикл
Сообщить ("" + СокрЛП(Ссылка[0]) + " " + СокрЛП(Ссылка[1]));
КонецЦикла;
Если по метатаднным, то так.
Смущает количество циклов...
Для Каждого Док Из Метаданные.Документы Цикл
Если Док.ТабличныеЧасти.Количество() > 0 Тогда
Для Каждого ТЧ из Док.ТабличныеЧасти Цикл
Для Каждого Рек Из ТЧ.Реквизиты Цикл
Если Рек.Тип.СодержитТип(Тип("СправочникСсылка.НоменклатурныеГруппы")) Тогда
//Сообщить(Строка(Док) + " - " + Строка(ТЧ.Имя) + " - " + Строка(Рек.Имя) + " - " + Рек.Тип);
ДокВыборка = Документы[Док.Имя].Выбрать(Дата(2019,04,01), Дата(2019,07,30));
Пока ДокВыборка.Следующий() Цикл
ДокОбъект = ДокВыборка.Ссылка.ПолучитьОбъект();
ТЧОбъект = ДокОбъект[ТЧ.Имя];
Для Каждого Стр Из ТЧОбъект Цикл
Если ТипЗнч(Стр[Рек.Имя]) = Тип("СправочникСсылка.НоменклатурныеГруппы") Тогда
Сообщить("OK");
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
ITF, количество циклов вполне нормальное. Только не понятно зачем внутри проверять на равность типа Тип("СправочникСсылка.НоменклатурныеГруппы"), если выше уже проверили на содержание типа - сразу сравнивай значение с искомым, не теряй время.
Дмитрий Кинаш, первая проверка идёт непосредственно реквизита как объекта метаданных, т.к. у него обычно стоит список типов, и там помимо нужного могут быть и другие. Для сокращения числа видов документов.
А вторая проверка, именно значения, что бы значения другого типа не затереть случайно, если реквизит может принимать их разные.
Как например в документе "АвансовыеОтчеты", где в табличной части "Прочее", в качестве субконто могут быть все существующие субконто.
Дмитрий Кинаш, попробую ещё по "НайтиПоСсылкам()".
Не знаю быстрее ли будет. Примеры в интернете гляну, пока тяжело даётся понимание как адаптировать под мою задачу.
ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ Справочник.НоменклатурныеГруппы";
Запрос = Новый Запрос(ТекстЗапроса);
СписокСсылок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
СсылкиНаДокументы = НайтиПоСсылкам(СписокСсылок);
Для Каждого СД Из СсылкиНаДокументы Цикл
Сообщить("OK");
КонецЦикла;
Я правильно понимаю что он не даёт конкретные места ссылок?
И что дальше, я вытаскиваю документы где используется и начинаю перебирать как в предыдущем варианте?