1

Тема: 1Cv8.0: некоторые вопросы программирования и проектирования

Как получить программный доступ к движениям документа? Данный вопрос может возникнуть при желании написать, например, более-менее универсальный микро-отчётик по движениям документа. Можно начать с перебора регистров, которые могут двигаться документом. В схематичном примере ниже "Док" должен иметь тип "ДокументОбъект", а полученный элемент коллекции "Дв" будет иметь тип "ОбъектМетаданных" (регистр).

Для Каждого Дв Из Док.Метаданные().Движения Цикл
    // Дв.Измерения - коллекция измерений регистра
    // Дв.Ресурсы - коллекция ресурсов регистра
    // Дв.Реквизиты - коллекция реквизитов регистра
    // находим максимальное количество (для будущего перебора в цикле):
    МаксКол = Макс(Дв.Измерения.Количество(), Дв.Ресурсы.Количество(), Дв.Реквизиты.Количество());
    // НаборЗаписей - коллекция движений по заданному регистру
    НаборЗаписей = Док.Движения[Дв.Имя];
    НаборЗаписей.Прочитать();
    Для Каждого Запись Из НаборЗаписей Цикл
        Для i = 0 По МаксКол-1 Цикл
            Если i < Дв.Измерения.Количество() Тогда
                ЗначИзмерения = Запись[Дв.Измерения[i].Имя];
            КонецЕсли;
            Если i < Дв.Ресурсы.Количество() Тогда
                ЗначРесурса = Запись[Дв.Ресурсы[i].Имя];
            КонецЕсли;
            Если i < Дв.Реквизиты.Количество() Тогда
                ЗначРеквизита = Запись[Дв.Реквизиты[i].Имя];
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
КонецЦикла;
Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

2

Re: 1Cv8.0: некоторые вопросы программирования и проектирования

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

ЭлементыФормы.<ИмяТабличногоПоля>.НастройкаПорядка.<ИмяРеквизита>.Доступность = Истина;

Подобным же образом можно поступить и на форме списка документа.

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

3

Re: 1Cv8.0: некоторые вопросы программирования и проектирования

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

1. Делаем кнопку подбора на форме документа любым способом, в процедуре этой кнопки пишем примерно следующее:

ФормаПодбора = Обработки.<ИмяОбработки>.ПолучитьФорму(, ЭтаФорма);
ТаблЗнач = ФормаПодбора.ЭлементыФормы.<ИмяТабличногоПоля>.Значение;
//заполняем таблицу для выбора:
НовСтр = ТаблЗнач.Добавить();
НовСтр.<ИмяКолонки> = <Значение>;
// ... и т.д.
ФормаПодбора.Открыть(); // можно и ОткрытьМодально()

2. В процедуре ОбработкаВыбора(ЗначениеВыбора, Источник) формы документа пишем необходимый код, заполняющий строку табличной части, который будет исполнен в момент выбора. Наподобие такого:

Если ТипЗнч(ЗначениеВыбора) = Тип("СтрокаТаблицыЗначений") Тогда
    Стр = <ИмяТабличнойЧасти>.Найти(ЗначениеВыбора.<ИмяРеквизита>, "<ИмяРеквизита>");
    Если Стр = Неопределено Тогда
        Стр = <ИмяТабличнойЧасти>.Добавить();
        Стр.<ИмяРеквизита> = ЗначениеВыбора.<ИмяРеквизита>;
        // ... и т.д.
    Иначе
        ЭлементыФормы.<ИмяТабличнойЧасти>.ТекущаяСтрока = Стр;
    КонецЕсли;
КонецЕсли;

3. На форме обработки в обработчике события "Выбор" табличного поля <ИмяТабличногоПоля>Выбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка) пишем примерно следующее:

СтандартнаяОбработка = Ложь;
ОповеститьОВыборе(ВыбраннаяСтрока);
Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

4

Re: 1Cv8.0: некоторые вопросы программирования и проектирования

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

1. Создать в конфигурации новый План видов характеристик "СвойстваКонтрагентов". Свойство "Тип значения характеристик" этого Плана видов характеристик определяет составной тип данных, в который входят все типы, которые могут понадобиться при указании типа значения характеристики. Если пользователю станет недостаточно этих типов данных (например, он захочет вести учет в разрезе городов Контрагентов, а справочника "Города" в конфигурации нет), он сможет воспользоваться неким вспомогательным справочником, который разработчик создаст заблаговременно и укажет в качестве свойства Плана видов характеристик - "Дополнительные значения характеристик". Этот справочник должен быть подчинённым плану видов характеристик. Таким образом, если затем пользователь пожелает создать характеристики "Страна" и "Город", он будет задавать их значения в том же самом справочнике дополнительных характеристик, но они не будут "смешиваться" друг с другом при выборе.

2. Создать в конфигурации новый справочник "ЗначенияСвойствКонтрагентов". В качестве владельца справочника назначить План видов характеристик "СвойстваКонтрагентов".

3. Свойство "Тип значения характеристик" Плана видов характеристик "СвойстваКонтрагентов" задать как "СправочникСсылка.ЗначенияСвойствКонтрагентов" (мы рассматриваем простейший случай, у нас составной тип будет состоять только из одного типа). Свойство "Дополнительные значения характеристик" задать так же: как "ЗначенияСвойствКонтрагентов".

4. Создать в конфигурации новый непериодический регистр сведений "ЗначенияСвойствКонтрагентов" с независимым режимом записи. Измерения: "Контрагент" (СправочникСсылка.Контрагенты), "Свойство" (ПланВидовХарактеристикСсылка.СвойстваКонтрагентов). Ресурс - "Значение" (Характеристика.СвойстваКонтрагентов).

5. На форме элемента справочника "Контрагенты" разместить табличное поле с типом значения "РегистрСведенийСписок.ЗначенияСвойствКонтрагентов". Колонку "Контрагент" в табличном поле можно убрать, т.к. значения всё равно надо фильтровать по текущему контрагенту (т.е. контрагент во всех строках будет всегда одним и тем же - текущим контрагентом, чья форма сейчас открыта).

6. В обработчике события "При открытии" формы элемента справочника "Контрагенты" необходимо задать фильтр по текущему контрагенту:

<ИмяТабличногоПоля>.Отбор.Контрагент.Использование = Истина;
<ИмяТабличногоПоля>.Отбор.Контрагент.Значение = Ссылка;

7. В обработчике события "При начале редактирования" <ИмяТабличногоПоля>ПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование) табличного поля, расположенного на форме элемента справочника "Контрагенты", необходимо заполнить поле "Контрагент", т.к. мы убрали его видимую колонку:

Если НоваяСтрока Тогда
    Элемент.ТекущиеДанные.Контрагент = Ссылка;
КонецЕсли;

8. В обработчике события "Перед началом добавления" <ИмяТабличногоПоля>ПередНачаломДобавления(Элемент, Отказ, Копирование) табличного поля, расположенного на форме элемента справочника "Контрагенты", необходимо проверить, записан ли текущий Контрагент, чтобы предотвратить исключительную ситуацию при записи данных в регистр сведений:

Если ЭтотОбъект.ЭтоНовый() Тогда
    Предупреждение("Для редактирования свойств Контрагент должен быть записан!");
    Отказ = Истина;
КонецЕсли;
Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

5

Re: 1Cv8.0: некоторые вопросы программирования и проектирования

Как сохранить в 1С-базе данных двоичные файлы в реквизитах справочника?
Предположим, необходимо хранить фото и/или видео для контрагентов. Создадим в справочнике "Контрагенты" табличную часть "Файлы" с реквизитами "ИмяФайла" (Строка, 256) и "Файл" (ХранилищеЗначения). На форме элемента справочника "Контрагенты" разместим табличное поле, ссылающееся на табличную часть "Файлы". Колонку "Файл" (реквизит табличной части) визуально выводить не надо.

Загрузка и сохранение файла в базе (по какой-нибудь кнопке) может выглядеть примерно так:

Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл для записи в базу данных";
Диалог.Фильтр = "Все файлы (*.*)";
Диалог.ПроверятьСуществованиеФайла = Истина;
Диалог.ПредварительныйПросмотр = Истина;
Если Диалог.Выбрать() = Ложь Тогда
    Возврат;
КонецЕсли;
ДвоичныеДанные = Новый ДвоичныеДанные(Диалог.ПолноеИмяФайла);
ЭлементыФормы.<ИмяТабличногоПоля>.ТекущиеДанные.Файл = Новый ХранилищеЗначения(ДвоичныеДанные);
Файл = Новый Файл(Диалог.ПолноеИмяФайла);
ЭлементыФормы.<ИмяТабличногоПоля>.ТекущиеДанные.ИмяФайла = Файл.Имя;

Таким образом, в реквизите "ИмяФайла" мы сохраним имя загруженного файла (без пути), которое может предоставлять некоторую информацию о файле пользователю + пригодится нам при сохранении этого файла на диске.

Сохранение файла из базы на диск по запросу пользователя (по какой-нибудь кнопке) может выглядеть примерно так:

ДвоичныеДанные = ЭлементыФормы.<ИмяТабличногоПоля>.ТекущиеДанные.Файл.Получить();
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Заголовок = "Сохранить файл как";
Диалог.Фильтр = "Все файлы (*.*)";
Диалог.ПолноеИмяФайла = ТекущиеДанные.ИмяФайла;
Если Диалог.Выбрать() = Ложь Тогда
    Возврат;
КонецЕсли;
Попытка
    ДвоичныеДанные.Записать(Диалог.ПолноеИмяФайла);
Исключение
    Сообщить("Не удалось сохранить файл. Возможно, файл пуст (отсутствует).", СтатусСообщения.Важное);
КонецПопытки;

И наконец, открытие файла для просмотра или воспроизведения средствами операционной системы (по какой-нибудь кнопке) может выглядеть примерно так:

ДвоичныеДанные = ЭлементыФормы.<ИмяТабличногоПоля>.ТекущиеДанные.Файл.Получить();
Попытка
    ДвоичныеДанные.Записать(КаталогВременныхФайлов()+ЭлементыФормы.<ИмяТабличногоПоля>.ТекущиеДанные.ИмяФайла);
Исключение
    Сообщить("Не удалось извлечь файл. Возможно, файл пуст (отсутствует).", СтатусСообщения.Важное);
    Возврат;
КонецПопытки;
ЗапуститьПриложение(КаталогВременныхФайлов()+ЭлементыФормы.<ИмяТабличногоПоля>.ТекущиеДанные.ИмяФайла);
Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

6

Re: 1Cv8.0: некоторые вопросы программирования и проектирования

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

1. Добавить новую колонку в табличное поле на форме.

2. В обработчике события табличного поля "При выводе строки" <ИмяТабличногоПоля>ПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) написать примерно следующее:

ОформлениеСтроки.Ячейки.<ИмяКолонки>.ОтображатьТекст = Истина;
ОФормлениеСтроки.Ячейки.<ИмяКолонки>.Текст = "нужное значение";
Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

7

Re: 1Cv8.0: некоторые вопросы программирования и проектирования

Как исследовать структуру SQL-базы данных 1С?

Например, чтобы получить имя таблицы справочника, можно выполнить код, подобный следующему:

Рез = ЗначениеВСтрокуВнутр(Справочники.<ИмяСправочника>.ПустаяСсылка());

В полученном значении нужно взять то, что находится между второй запятой и двоеточием. Например, в конфигурации УТ для справочника "Склады" это будет число 44. В этом случае таблица справочника будет называться "_Reference44". Подобным образом можно поступить и с документами.
В общем ключе о размещении данных 1С в таблицах можно прочитать в статье "Размещение данных 1С:Предприятия 8.0" в разделе "Методическая поддержка 1С:Предприятия 8.0" на ежемесячных дисках ИТС (Информационно - технологического сопровождения).

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