Встала передо мной тут задачка одна - автоматизировать работу контролеров на рыке. Рынок поделен на торговые зоны.
Каждая зона разбита на ряды и на места. Трудность заключается в том, что в каждой зоне разное количество рядов, как и мест
в рядах. Нужно, чтобы контролер мог наглядно (схематически) видеть состояние той или иной зоны. Видеть занятые/свободные
места, для чего предназначено каждое место. Кроме того требуется сделать это все «динамически». Т.е. каждый месяц
количество рядов, мест и их назначение может меняться.
На первый взгляд задача не такая и трудная. Главное - как-то сохранить структуру зоны в 1С. Но как? Структура зоны
представляет собой не что иное, как обычную двумерную таблицу «шахматку». По вертикали места, по горизонтали ряды. Т.е.
оптимальный вариант – использование таблицы значений в 1С. Но, к сожалению, 1С не умеет хранить ТЗ в составе базы. Есть
несколько вариантов хранить ТЗ. Во-первых, во внешнем файле. Во-вторых, во внешнем dbf’е. В-третьих, создать справочник
(несколько справочников). И последний вариант – документ с табличными реквизитами.
Первый способ отметаем сразу, второй немного лучше первого, но все равно хранить что-то отдельно от базы не всегда
удачное решение, да и трудностей больше. Третий способ предлагали многие, но он мне не понравился. Представьте себе зону
100 на 100… Пусть даже справочник будет заполняться программно. Геморрой… А еще если учесть что реквизиты справочника
должны быть периодическими, то хочется плакать. Четвертый вариант – вот оно! То что нужно! Точнее, это единственный верный
вариант в данном случае.
Итак, для хранения ТЗ используем документ с реквизитом шапки – Зона и табличными реквизитами – ряд, место,
назначение. Зона – справочник «Структура торговой зоны», где указано количество рядов в зоне и максимальное количество мест
в ряду. Но как заполнять такой документ? Согласитесь, очень неудобно десять раз указать ряд, десять раз выбрать место, а
потом еще и назначение этого места. Утомительно и трудно для восприятия. Отсюда возможные ошибки. Вот тут и возникла идея -
заполнять документ, используя таблицу! Таким образом, табличные реквизиты вообще можно не выводить в документе…
После начала реализации, понял, а ведь это очень удобно использовать таблицу для ввода всевозможных данных в 1С.
Кроме того ее можно использовать не только для ввода, но и для вывода, в том числе и динамического. Да и еще кучу
применений можно придумать!Так родилась идея создания универсальной таблицы для ввода данных. На входе указываем количество
рядов и мест, на выходе получаем ТЗ…
Делаем таблицу…
В свойствах формы обработки/отчета выбираем использовать таблицу для ввода данных (Положение: любое).
Для начала нам надо сформировать таблицу…
// Формирование произвольной таблицы. // Параметры: КолвоРядов - кол-во рядов в зоне // КолвоМест - макс. кол-во мест в ряде. //==================================================================== Процедура СформироватьСхему(КолвоРядов, КолвоМест) // Начальные значения координат первой(верхняя левая) ячейки x = 4;y =3; НачалоТаблицы = "R"+x+"C"+y; КоординатыЯчеек.УдалитьВсе(); // КоординатыЯчеек – Список значений(как глобальная переменная модуля). Пригодиться в дальнейшем при обработке // нажатия на ячейке мышкой. Чтобы не обрабатывались не входящие в схему ячейки. Ячейка = Таблица.Область("R"+(x-1)+"C"+(y-1)); Ячейка.РамкаОбвести(,,3,3); Ячейка.Текст = "место №"; Ячейка = Таблица.Область("R"+(x-2)+"C"+y); Ячейка.Текст = "ряд №"; Для i = 0 По КолвоМест-1 Цикл Для j = 0 По КолвоРядов-1 Цикл // Формируем таблицу x/y АдресЯчейки = "R"+(x+i)+"C"+(y+j); Ячейка = Таблица.Область(АдресЯчейки); Ячейка.Контроль(4); Ячейка.ЦветФона(255,255,128); Ячейка.РамкаОбвести(3,3,3,3); Ячейка.Текст = "-"; КоординатыЯчеек.ДобавитьЗначение(АдресЯчейки); // выводим ряды АдресЯчейки = "R"+(x-1)+"C"+(y+j); Ячейка = Таблица.Область(АдресЯчейки); Ячейка.РамкаОбвести(3,3,3,); Ячейка.ЦветФона(192,192,192); Ячейка.Текст = j+1; КонецЦикла; // выводим места АдресЯчейки = "R"+(x+i)+"C"+(y-1); Ячейка = Таблица.Область(АдресЯчейки); Ячейка.РамкаОбвести(3,,,3); Ячейка.ЦветФона(192,192,192); Ячейка.Текст = i+1; КонецТаблицы = "R"+(x+КолвоМест-1)+"C"+(y+КолвоРядов-1); //обводим поученную таблицу рамкой КонецЦикла; Область = Таблица.Область(НачалоТаблицы+":"+КонецТаблицы); Область.РамкаОбвести(3,3,3,3); Таблица.Опции(0,,3,2,"СхемаТоргМест","СхемаТоргМест"); КонецПроцедуры
Вот что у нас получилось (рядов 10, мест 10): рис. 1
Теперь надо сделать так, чтобы в ячейки можно было вносить какие-то данные, например из справочника. Замечу, что
ячейки таблицы в режиме ввода данных могут быть любого типа (по умолчанию у всех стоит тип «строка»). Т.е. если мы в
конфигураторе укажем заранее, что ячейка имеет тип Справочник.XXX. То при работе в эту ячейку можно вносить элементы из
указанного справочника. А саму таблицу потом выгружать в список значений методом Выгрузить(). Тут меня ждало первое
разочарование…
Поскольку заранее мы не знаем количество рядов/мест, то какие ячейки будут иметь нужный нам тип надо сделать
программно. Да и метод такой имеется УстановитьТип(). Но этот метод применим, если на этапе конфигурирования ячейке
назначен тип – «Неопределенный», а по умолчанию, как я уже писал, у всех ячеек тип «строка». Предположив, что на практике
вряд ли будет существовать зона 100 рядов на 100 мест, я, не долго думая, выделил в конфигураторе область 100 на 100 и
назначил всем ячейкам тип «Неопределенный». Сохранил отчет и … отчет стал весить 64(!!!) Мегабайта….) Мда, так не пойдет… и
я придумал другой выход...
При открытии обработки формируем таблицу значений, которая по структуре идентична нашей таблице. Т.е. количество
строк будет равно количеству мест, а количество колонок – количеству рядов. Тип колонок выбираете произвольно, или
«неопределенный». Таким образом, эта ТЗ будет являться своего рода «подложкой» нашей таблицы и полностью дублировать ее. Эту ТЗ мы и передаем во внешний документ, вызвавший эту обработку.
Теперь напишем обработку ячейки таблицы. Замечу, что в моем примере, значение пользователем выбирается из списка
значений (меню), т.к. возможных значений у меня немного. Вы можете сделать выбор значения как угодно: открывать справочник
для подбора, открывать СЗ в любом доступном виде или вообще сварганить многоуровневое меню, как описал Che Burshka там - //infostart.ru/profile/174/articles/178/.
Процедура ПриВыбореЯчейкиТаблицы(Адрес,Значение) Перем х,у; //координаты ячейки Если КоординатыЯчеек.Принадлежит(Адрес) = 0 Тогда Возврат; КонецЕсли; Элемент = ""; Если СЗ.ВыбратьЗначение(Элемент,,,,1) = 1 Тогда Ячейка = Таблица.Область(Адрес); ПолучитьКоординатыЯчейки(Адрес,х,у); Попытка Ячейка.Значение = СокрЛП(Элемент.Наименование); Ячейка.ЦветФона(128,255,128); Ячейка.РамкаОбвести(3,3,3,3); ТЗ.УстановитьЗначение(х,у, Элемент); Исключение // все элементы СЗ имеют тип Справочник.ХХХ, т.е. имеют реквизит «Наименование», //если такого реквизита нет – значит этот пункт меню служит для удаления значения ячейки. Ячейка.Значение = "-"; Ячейка.ЦветФона(255,255,128); ТЗ.УстановитьЗначение(х,у, ""); КонецПопытки; КонецЕсли; КонецПроцедуры
Получаем вот такое меню: рис.2
Итоговый вид таблицы после заполнения оператором: рис.3
Демонстрационная обработка здесь -> //infostart.ru/projects/1299/
В демонстрационной обработке используются значения типа "Строка".
Рис.1
Рис. 2
Рис. 3