Библиотека кода: Сравнить две таблицы значений Код 1C v 8.х
//Сравнивает две таблицы значений
//
Функция ТаблицыЗначенийРавны(ТаблицаЗначений1, ТаблицаЗначений2) Экспорт
Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда
Возврат Ложь;
КонецЕсли;
// Проверим поля
Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Для каждого Колонка Из ТаблицаЗначений2.Колонки Цикл
Если ТаблицаЗначений1.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
// сформируем строку индекса для оптимизации поиска по таблице значений
СтрокаИндекса = "";
Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
Если СтрокаИндекса = "" Тогда
СтрокаИндекса = Колонка.Имя;
Иначе
СтрокаИндекса = СтрокаИндекса+","+Колонка.Имя;
КонецЕсли;
КонецЦикла;
// добавим индекс
ТаблицаЗначений2.Индексы.Добавить(СтрокаИндекса);
// Проверим записи
Для каждого СтрокаТаблицы Из ТаблицаЗначений1 Цикл
СтруктураПоиска = Новый Структура;
Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
СтруктураПоиска.Вставить(Колонка.Имя, СтрокаТаблицы[Колонка.Имя]);
КонецЦикла;
СтрокиТаблицы2 = ТаблицаЗначений2.НайтиСтроки(СтруктураПоиска);
Если СтрокиТаблицы2.Количество() <> 1 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
// сформируем строку индекса для оптимизации поиска по таблице значений
СтрокаИндекса = "";
Для каждого Колонка Из ТаблицаЗначений2.Колонки Цикл
Если СтрокаИндекса = "" Тогда
СтрокаИндекса = Колонка.Имя;
Иначе
СтрокаИндекса = СтрокаИндекса+","+Колонка.Имя;
КонецЕсли;
КонецЦикла;
// добавим индекс
ТаблицаЗначений1.Индексы.Добавить(СтрокаИндекса);
Для каждого СтрокаТаблицы Из ТаблицаЗначений2 Цикл
СтруктураПоиска = Новый Структура;
Для каждого Колонка Из ТаблицаЗначений2.Колонки Цикл
СтруктураПоиска.Вставить(Колонка.Имя, СтрокаТаблицы[Колонка.Имя]);
КонецЦикла;
СтрокиТаблицы1 = ТаблицаЗначений1.НайтиСтроки(СтруктураПоиска);
Если СтрокиТаблицы1.Количество() <> 1 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции// СравнитьТаблицыЗначений()
Категория:
Полезные, Универсальные Функции Преобразование ТаблицыЗначений во временную таблицу Код 1C v 8.х Процедура ПреобразоватьТЗвТЗсОписаниемТипов(ТЗ)
ТипизированнаяТЗ = Новый ТаблицаЗначений;
Для й=1 По Тз.Количество() Цикл ТипизированнаяТЗ.Добавить(); //Создаем строки
КонецЦикла;
ДЗТипов = Новый ДеревоЗначений;
ДЗТипов.Колонки.Добавить("ИмяКолонки");
ДЗТипов.Колонки.Добавить("ТипЗначений");
Для Каждого Колонка из Тз.Колонки Цикл
СтрокаКолонки = ДЗТипов.Строки.Добавить();
СтрокаКолонки.ИмяКолонки = Колонка.Имя;
ТекСТрокаТипа = СтрокаКолонки.Строки.Добавить();
ТекСТрокаТипа.ИмяКолонки = Колонка.Имя; //Заполняется для красоты
ТекСТрокаТипа.ТипЗначений = ТипЗнч(тз[0][Колонка.Имя]);
Для Каждого СтокаТЗ из Тз Цикл
ТекТип = ТипЗнч(СтокаТЗ[Колонка.Имя]);
Если НЕ ТекТип = ТекСТрокаТипа.ТипЗначений Тогда
Если СтрокаКолонки.Строки.Найти(ТекТип, "ТипЗначений")=Неопределено Тогда
ТекСТрокаТипа = СтрокаКолонки.Строки.Добавить();
ТекСТрокаТипа.ИмяКолонки = Колонка.Имя;//Заполняется для красоты
ТекСТрокаТипа.ТипЗначений = ТекТип;
КонецЕслИ;
КонецЕслИ;
КонецЦикла;
МассивТипов = СтрокаКолонки.Строки.ВыгрузитьКолонку("ТипЗначений");
ТипизированнаяТЗ.Колонки.Добавить(Колонка.Имя, Новый ОписаниеТипов(МассивТипов),Колонка.Заголовок);
ТипизированнаяТЗ.ЗагрузитьКолонку(Тз.ВыгрузитьКолонку(Колонка),Колонка.Имя);
КонецЦикла;
КонецПроцедуры
Источник
Категория:
Запросы Объединение 2 таблиц значений Код 1C v 8.х // Объединить 2 таблицы значения
// тзОсновная - таблица к которой будут изменяться данные
// тзПрисоединяемая - таблица из которой будут браться данные
// стОтборОдинаковых - стурктура со списком полей по которым определяеться одинаковость записи
// ДобавлятьНеНайденное - ИСТИНА => не сущесвующие записи в тзОсновная будут браться из тзПрисоединяемая
Процедура ОбъединитьТаблицыЗначений(тзОсновная,тзПрисоединяемая, стОтборОдинаковых, ДобавлятьНеНайденное = Ложь) Экспорт
Для каждого текПрисоединяемаяЗапись из тзПрисоединяемая цикл
ЗаполнитьЗначенияСвойств(стОтборОдинаковых,текПрисоединяемаяЗапись);
НайденыеСтроки = тзОсновная.НайтиСтроки(стОтборОдинаковых);
Если НайденыеСтроки.Количество() > 0 тогда
Для каждого текНайденная из НайденыеСтроки цикл
ЗаполнитьЗначенияСвойств(текНайденная,текПрисоединяемаяЗапись);
КонецЦикла;
ИначеЕсли ДобавлятьНеНайденное тогда
НовСтрокаОсновном = тзОсновная.Добавить();
ЗаполнитьЗначенияСвойств(НовСтрокаОсновном,текПрисоединяемаяЗапись);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Категория:
Работа с Таблицей Значений Как произвести поиск нескольких строк в "ТаблицаЗначений" по двум и более полям? Для поиска нескольких строк предназначен метод НайтиСтроки.
В платформе он определен таким образом.
Код 1C v 8.х НайтиСтроки( <Параметры_Отбора>)
Где
<Параметры_Отбора> представляют структуру, в которой ключ структуры определяет имя колонки, а значение структуры - искомое значение. Возвращает этот метод массив строк ТаблицыЗначений.
Стоит помнить, что массив содержит не копии строк, а ссылки на строки таблицы источника! Т.е. внеся изменения в строку из массива, вы изменяете строки в таблице.
Добавляя в структуру несколько записей вы, соответственно, устанавливаете отбор по нескольким полям.
Выглядит это примерно вот так:
Код 1C v 8.х ТЗРабочихДнейПоГрафику = Новый ТаблицаЗначений;
ТЗРабочихДнейПоГрафику.Колонки.Добавить("месяцИнтервала");
ТЗРабочихДнейПоГрафику.Колонки.Добавить("График");
ТЗРабочихДнейПоГрафику.Колонки.Добавить("РабочихДней");
...
ОтборПоГрафику = Новый Структура;
ОтборПоГрафику.Вставить("месяцИнтервала", СтрокаПериода.МесяцПериода);
ОтборПоГрафику.Вставить("График", Групп_Задача.График);
НайденныеСтроки = ТЗРабочихДнейПоГрафику.НайтиСтроки(ОтборПоГрафику);
Автор: Андрей Окипний
Категория:
Работа с Таблицей Значений Преобразование дерева значений в таблицу значений и обратно Хочу поделиться с посетителями сайта своим подходом к преобразованию таблицы значений в дерево значений и обратно.
Вообще, при разработке отраслевой задачи, была необходимость почти во всех документах, выводить информацию в виде дерева и хранить ее в табличных частях документа, а также в интерактивной обработке данных в виде дерева.
Отсюда появился небольшой модуль для расширения возможности работы с деревом значений, хотя и с некоторыми оговорками.
Основной идеей является использование двух ключевых реквизитов/колонок КлючСтроки и КлючСвязи.
Однако они не всегда необходимы. Код, на мой взгляд достаточно "высушен".
Код 1C v 8.х ////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ РАБОТЫ С ДЕРЕВОМ ЗНАЧЕНИЙ
// Функция формирует значение нового ключа строки табличной части.
//
// Параметры:
// Дерево - дерево значений
//
Функция ПолучитьНовыйКлючСтрокиДерева(Дерево, СписокКлючей = Неопределено) Экспорт
Если СписокКлючей = Неопределено Тогда
СписокКлючей = Новый СписокЗначений;
СписокКлючей.Добавить(0);
КонецЕсли;
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
СписокКлючей.Добавить(СтрокаДерева.КлючСтроки);
ПолучитьНовыйКлючСтрокиДерева(СтрокаДерева, СписокКлючей);
СписокКлючей.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
МаксКлюч = СписокКлючей[0].Значение + 1;
КонецЦикла;
Возврат МаксКлюч;
КонецФункции // ПолучитьНовыйКлючСтрокиДерева()
// Процедура обновляет ключи связи в дереве значений
//
Процедура ОбновитьКлючиСвязиВДеревеЗначений(Дерево) Экспорт
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
Попытка
СтрокаДерева.КлючСвязи = СтрокаДерева.Родитель.КлючСтроки;
Исключение
СтрокаДерева.КлючСвязи = 0;
КонецПопытки;
ОбновитьКлючиСвязиВДеревеЗначений(СтрокаДерева);
КонецЦикла;
КонецПроцедуры // ОбновитьКлючиСвязиВДеревеЗначений()
// Процедура обновляет ключи связи в дереве значений
//
Процедура ОбновитьКлючиСтрокВДеревеЗначений(Дерево, КлючСтроки = 1) Экспорт
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
СтрокаДерева.КлючСтроки = КлючСтроки;
КлючСтроки = КлючСтроки + 1;
ОбновитьКлючиСтрокВДеревеЗначений(СтрокаДерева, КлючСтроки);
КонецЦикла;
КонецПроцедуры // ОбновитьКлючиСвязиВДеревеЗначений()
// Процедура выгружает данные из дерева значений в таблицу значений
// данные выгружаются только в таблицу со сходным набором реквизитов
//
Функция ВыгрузитьДеревоЗначенийВТаблицуЗначений(Дерево, Таблица = Неопределено) Экспорт
Если Таблица = Неопределено Тогда
Таблица = Новый ТаблицаЗначений;
Для Каждого Колонка Из Дерево.Колонки Цикл
Таблица.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
КонецЕсли;
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
ЗаполнитьЗначенияСвойств(Таблица.Добавить(), СтрокаДерева);
ВыгрузитьДеревоЗначенийВТаблицуЗначений(СтрокаДерева, Таблица);
КонецЦикла;
Возврат Таблица;
КонецФункции //ВыгрузитьДеревоЗначенийВТаблицуЗначений()
// Процедура выгружает данные из таблицы значений в дерево значений
// данные выгружаются только в таблицу со сходным набором реквизитов
//
// Параметры:
//
// КлючСтроки - имя колонки ТаблицыЗначений - уникальный идентификатор
// КлючСвязи - имя колонки ТаблицыЗначений - указатель привязки к строке Дерева,
// своего рода указатель на "Родителя"
//
Функция ВыгрузитьТаблицуЗначенийВДеревоЗначений(Таблица, КлючСтроки = "КлючСтроки", КлючСвязи = "КлючСвязи") Экспорт
Дерево = Новый ДеревоЗначений;
Для Каждого Колонка Из Таблица.Колонки Цикл
Дерево.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
Для Каждого СтрокаТаблицы Из Таблица Цикл
СтрокаГруппировки = Дерево.Строки.Найти(СтрокаТаблицы[КлючСвязи], КлючСтроки,Истина);
Если СтрокаГруппировки = Неопределено Тогда
ЗаполнитьЗначенияСвойств(Дерево.Строки.Добавить(), СтрокаТаблицы);
Иначе
ЗаполнитьЗначенияСвойств(СтрокаГруппировки.Строки.Добавить(), СтрокаТаблицы);
КонецЕсли;
КонецЦикла;
Возврат Дерево;
КонецФункции //ВыгрузитьТаблицуЗначенийВДеревоЗначений()
// Процедура устанавливает значение во всем дереве значений
//
Процедура УстановитьЗначениеКолонкиДерева(Дерево, Колонка, Значение) Экспорт
Для каждого СтрокаДерева Из Дерево.Строки Цикл
СтрокаДерева[Колонка] = Значение;
УстановитьЗначениеКолонкиДерева(СтрокаДерева, Колонка, Значение);
КонецЦикла;
КонецПроцедуры //УстановитьЗначениеКолонкиДерева()
// Процедура копирует подчиненные строки дерева значений
//
Процедура СкопироватьПодчиненныеСтроки(СтрокаПриемник, СтрокаИсточник)
Для каждого Строка Из СтрокаИсточник.Строки Цикл
НоваяСтрока = СтрокаПриемник.Строки.Добавить();
НоваяСтрока.КлючСвязи = СтрокаПриемник.КлючСтроки;
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
СкопироватьПодчиненныеСтроки(НоваяСтрока, Строка);
КонецЦикла;
КонецПроцедуры // СкопироватьПодчиненныеСтроки()
// Процедура переносит выделенные строки дерева значений в указанную ветку
//
Процедура ПеренестиСтрокиДереваЗначений(СтрокаПриемник, ВыделенныеСтроки) Экспорт
Если НЕ СтрокаПриемник = Неопределено Тогда
МассивСтрок = Новый Массив;
Для Каждого СтрокаПереноса Из ВыделенныеСтроки Цикл
МассивСтрок.Добавить(СтрокаПереноса);
НоваяСтрока = СтрокаПриемник.Строки.Добавить();
СкопироватьПодчиненныеСтроки(НоваяСтрока, СтрокаПереноса);
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаПереноса);
НоваяСтрока.КлючСвязи = СтрокаПриемник.КлючСтроки;
КонецЦикла;
Для Каждого СтрокаДерева Из МассивСтрок Цикл
Если СтрокаДерева.Родитель = Неопределено Тогда
СтрокаДерева.Строки.Удалить(СтрокаДерева);
Иначе
СтрокаДерева.Родитель.Строки.Удалить(СтрокаДерева);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры //ПеренестиСтрокиДереваЗначений()
Александр Синцов (Sintson) Категория:
Работа с Деревом Значений Создание нового документа Для 8.2:
Открыть форму нового документа и предоставить пользователю самому интерактивно записать данные объекта в базу данных:
проще всего использовать метод глобального контекста ОткрытьФорму(). Это можно сделать на клиенте.
Код 1C v 8.2 УП ОткрытьФорму("Документ.ПриходнаяНакладная.ФормаОбъекта");
При этом создается новый документ и открывается для редактирования основная форма этого документа.
Если нужно какое-то предварительное заполнение документа начальными данными, то это можно сделать либо с помощью свойств реквизитов документа ЗначениеЗаполнения, ЗаполнятьИзДанныхЗаполнения либо в обработчике события документа ОбработкаЗаполнения.
Создать новый документ программно, программно заполнить его данными и программно записать. Затем, если нужно, показать его пользователю:
можно программно создать документ на сервере, заполнить данными, если это нужно в обработчике события ОбработкаЗаполнения, записать, и передать ссылку на новый документ в метод глобального контекста ОткрытьЗначение(), который откроет форму этого документа. Например:
Код 1C v 8.2 УП &НаКлиенте
Процедура ПриходнаяНакладная(Команда)
СсылкаНаДокумент = СоздатьНовыйДокумент();
ОткрытьЗначение(СсылкаНаДокумент);
КонецПроцедуры
&НаСервере
Функция СоздатьНовыйДокумент()
НовыйДокумент = Документы.ПриходнаяНакладная.СоздатьДокумент();
НовыйДокумент.Номер = "111";
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Записать();
Возврат НовыйДокумент.Ссылка;
КонецФункции
Подробнее об использовании методов ОткрытьЗначение() и ОткрытьФорму() можно прочитать в синтакс-помощнике: Глобальный контекст - Процедуры и функции для интерактивной работы
Код 1C v 8.2 УП // ЕЩЕ ПРИМЕР:
&НаКлиенте
Процедура СоздатьНовыйДокумент(Команда)
// Вставить содержимое обработчика.
Если СоздатьНовыйДокументНаСервере() = 0 Тогда
Сообщить("Не удалось создать новый документ");
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция СоздатьНовыйДокументНаСервере()
Перем НоваяРасходнаяНакладная;
Перем СтрокаТЧ;
НоваяРасходнаяНакладная=ДокРасходнаяНакладная.СоздатьДокумент();
//Заполняем реквизиты шапки
НоваяРасходнаяНакладная.Дата= ТекущаяДата();
НоваяРасходнаяНакладная.Фирма =Справочники.Фирмы.ОсновнаяФирма;
НоваяРасходнаяНакладная.Контрагент=Справочники.Контрагенты.НайтиПоКоду("000000001");
НоваяРасходнаяНакладная.Склад=Справочники.Склады.ОсновнойСклад;
//Заполняем табличную часть
СтрокаТЧ=НоваяРасходнаяНакладная.ТЧТовары.Добавить();
СтрокаТЧ.Товар=Справочники.Номенклатура.НайтиПоКоду("000000002");
СтрокаТЧ.Цена=СтрокаТЧ.Товар.РозничнаяЦена;
СтрокаТЧ.Количество= 2;
СтрокаТЧ.Сумма=СтрокаТЧ.Цена*СтрокаТЧ.Количество;
Попытка
НоваяРасходнаяНакладная.Записать();
Возврат 1;
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
Для 8.1:
Код 1C v 8.х
//Создаем документ Выплата, Документ будет создан и показан пользователю, Но НЕ ЗАПИСАН
НовДок = Документы.ЗарплатаКВыплатеОрганизаций.ПолучитьФормуНовогоДокумента();
НовДок.Дата=ТекущаяДата();
НовДок.Организация=Организация;
НовДок.ПериодРегистрации=ПериодРегистрации;
НовДок.ответственный= глЗначениеПеременной("глТекущийПользователь");
НовДок.Комментарий="Выплата за "+МесяцСтрока;
НовДок.ЭлементыФормы.Комментарий.Доступность=Ложь;
Для Каждого ТекущаяСтрока Из ТаблицыЗначений Цикл // заполним табличную часть документа, из ТаблицыЗначений
НС=НовДок.зарплата.добавить();
нс.Авторасчет=истина;
нс.Физлицо = ТекущаяСтрока.Физлицо;
нс.ВыплаченностьЗарплаты=Перечисления.ВыплаченностьЗарплаты.НеВыплачено;
нс.сумма=ТекущаяСтрока.Результат;
КонецЦикла;
НовДок.Открыть();
//Для создания и записи документа используется следующий код:
НовДок = Документы.РасходнаяНакладная.СоздатьДокумент();
НовДок.Дата=ТекущаяДата();
НовыйДок.УстановитьНовыйНомер();
НовДок.Организация=Организация;
НовДок.ПериодРегистрации=ПериодРегистрации;
НовДок.ответственный= глЗначениеПеременной("глТекущийПользователь");
НовДок.Комментарий="Выплата за "+МесяцСтрока;
НовДок.ЭлементыФормы.Комментарий.Доступность=Ложь;
Для Каждого ТекущаяСтрока Из ТаблицыЗначений Цикл // заполним табличную часть документа, из ТаблицыЗначений
НС=НовДок.зарплата.добавить();
нс.Авторасчет=истина;
нс.Физлицо = ТекущаяСтрока.Физлицо;
нс.ВыплаченностьЗарплаты=Перечисления.ВыплаченностьЗарплаты.НеВыплачено;
нс.сумма=ТекущаяСтрока.Результат;
КонецЦикла;
НовДок.Записать();
//Или так:
НовыйДок = Документы.ПеремещениеТоваров.СоздатьДокумент();
НовыйДок.Дата = ПолеВводаДаты;
НовыйДок.УстановитьВремя();
НовыйДок.УстановитьНовыйНомер();
// Формирование табличной части
Для Н=1 По N Цикл
НоваяСтрока = НовыйДок.Товары.Добавить();
НоваяСтрока.Номенклатура = СтрокаДанных.Номенклатура;
// формируются другие реквизиты табличной части
КонецЦикла;
НовыйДок.Записать();
СписокДокументов.Добавить(НовыйДок.Ссылка);
Категория:
Документы