[версия для печати]
Дела интерфейсные. Штатные возможности.   
автор: Алексей Фёдоров.   
Каждый программист хочет создавать качественные программы. Это утверждение не требует доказательств. Однако, не все профессионалы ассоциируют слова «качественная» и «красивая». Казалось бы, программа работает быстро, выдает верный результат, имеет эргономичный интерфейс чего еще надо? Самую малость – сделать ее немного приятней для глаз пользователя.
Применительно к конфигурациям 1С:Предприятия, много полезной информации о разнообразии интерфейса можно почерпнуть в Методической конфигурации, которая распространяется на дисках ИТС. Мне хотелось бы рассказать о нескольких приемах, которые позволят вам сделать интерфейс в вашей конфигурации 1С:Предприятия выделяющимся из огромной безликой толпы типовых (и не очень) конфигураций. Приемы эти очевидны, но, к сожалению, не нашли отражение в методических материалах фирмы «1С».
Для начала нам потребуется полностью прозрачная иконка, которую необходимо поместить в библиотеку картинок конфигурации. Иконку эту можно создать в любом подходящем редакторе, например, в Image Editor, устанавливаемом вместе с Delphi. Только необходимо помнить, что иконка должна быть размером 32х32 пикселя, иначе 1С:Предприятие некорректно вставляет ее в библиотеку картинок (о чем честно предупреждает). При этом прозрачный цвет заменяется на черный.
Имея такую картинку в своей конфигурации, вы уже можете оживить интерфейс, получив в свое распоряжение несколько дополнительных видов рамки (см. рисунок 1). Но это далеко не все, на что способна пустота.

Рисунок 1
 
Наверное, вы видели в некоторых программах так называемые flat-кнопки, т.е. кнопки, которые не выпирают над формой, а как бы находятся на одном с ней уровне и при нажатии «проваливаются» в форму диалога. Обычно подобного вида кнопки используются на панелях инструментов, а так же на разнообразных информационных окнах. К сожалению в 1С:Предприятии не предусмотрена возможность хоть как-то управлять стилями реквизитов диалогов. Но с помощью нашей прозрачной иконки мы можем легко обойти эту недоработку (см. рисунок 2).

Рисунок 2
 
Кнопка с заголовком «Красивая кнопка» получена простым наложением картинки с прозрачной иконкой и стандартной кнопки. Для картинки установлена вдавленная рамка, и она стоит «ниже» в порядке обхода.
Кнопка с заголовком «Еще красивая кнопка» получена иначе. Здесь вместо прозрачной картинки используется обычная рамка группы. Очевидно, что правило с порядком обхода соблюдается и в этом случае – сначала должна идти кнопка, а потом рамка. Использовать тот или иной способ решать вам, это уже дело вкуса и личных предпочтений.
Мы добились чего хотели? Не совсем. Есть еще одна маленькая хитрость. Дело в том, что если мы просто расположим реквизиты формы, как описано выше, красивость нашей формы продержится только до первого нажатия нашей красивой кнопки. После нажатия (или просто после потери фокуса) кнопка выходит на первый план и полностью перекрывает картинку (рамку). В результате получаем обычную кнопку на форме.
Вы, наверное, уже заметили на рисунке 2 строчку «<<СостояниеФормы()>>». Это текст на форме, в поле «Формула» которого прописан вызов функции. Функция эта вызывается при каждом обновлении формы, а это именно то, что нам надо, чтобы доделать нашу красивую кнопку.
Текст функции будет примерно такой:
Функция СостояниеФормы()
	Форма.Картинка1.Видимость(0);
	Форма.Картинка1.Видимость(1);
	Форма.Рамка1.Видимость(0);
	Форма.Рамка1.Видимость(1);
КонецФункции
Здесь «Картинка1» - идентификатор картинки, которая обеспечивает «плоскость» нашей кнопки. Соответственно «Рамка1» - идентификатор рамки, служащей для той же цели во втором варианте.
Кнопка готова! Метод, конечно не идеален, при обновлении формы будет заметно небольшое «подрагивание» нашей кнопки. Да и перегрузка формы лишними реквизитами не слишком благотворно влияет на скорость прорисовки формы. Но за красоту всегда приходится чем-то платить, а подобная кнопка будет очень симпатично смотреться, например, в диалоге об истечении срока работы вашей конфигурации в демо-режиме.
Но вернемся к первому рисунку.
Разнообразные рамки это уже хорошо, однако мы не будем на этом останавливаться, а создадим на основе этих рамок прогресс-бар. Подобного реквизита часто очень не хватает при создании «долгоиграющих» отчетов. Оставлять пользователя перед замершим экраном вообще считается плохим тоном. Выводить в строку состояния информацию о текущем этапе работы - неплохой выход. Однако грамотно реализованный прогресс-бар позволит не только отображать ход работы отчета, но и создаст у пользователя впечатление, что отчет работает быстрее. Этот трюк используется во многих программах, вы и сами, наверняка не раз его замечали.
Итак, начнем создавать наш прогресс-бар.
Делать его мы будет не простым, а сдвоенным, чтобы создать видимость совсем уж запредельной загруженности машины работой. Внешний вид того, что у нас получится в итоге, показан на рисунке 3.

Рисунок 3
 
Для реализации такого прогресс-бара необходимо добавить на форму три реквизита: прозрачную картинку для отображения рамки и два текстовых реквизита для отображения собственно полос прогресса. Для обоих текстовых реквизитов установите шрифт Webdings. Так же задайте им идентификаторы – например, «Прогресс» - для быстрой полосы и «ПрогрессПолн» - для медленной. Для того, чтобы одна полоса не перекрывала другую установите в обоих реквизитах флажок «прозрачный фон». Порядок обхода на форме должен быть следующим: «Прогресс», «ПрогрессПолн» и Картинка.
Для демонстрации работы нашего прогресс-бара напишем в модуле отчета такой текст:
Процедура ТестПрогресса()
    Для и1 = 1 по 26 Цикл
        Для и2 = 1 по 26 Цикл
            Форма.Прогресс.Заголовок(СтрЗаменить(Формат("","С"+и2)," ","g"));
            Для пауза = 1 по 100 Цикл
                Состояние(100 - пауза);
            КонецЦикла;
        КонецЦикла;
        Форма.ПрогрессПолн.Заголовок(СтрЗаменить(Формат("","С"+и1)," ","/"));
    КонецЦикла;
    Форма.Прогресс.Заголовок("");
    Форма.ПрогрессПолн.Заголовок("");
КонецПроцедуры
Конечно же, при использовании прогресса в реальной работе лучше реализовать изменение положения полос в виде отдельных процедур. Но это уже скорее проблема кодинга, а не интерфейса.
Так же легко можно получить, например, вертикальный прогресс-бар. Попробуйте реализовать его самостоятельно. Уверен, вы тут же найдете множество мест для его применения.
Главное в подобных манипуляциях - точное расположение реквизитов относительно друг друга. Именно такая ювелирная точность потребуется нам далее для реализации еще более привлекательного интерфейсного решения – закладок, которые в отличии от штатных можно будет расположить в любом месте формы.
Подобные закладки целесообразно делать в формах, где, например, верхняя часть остается постоянной, а нижняя должна меняться в зависимости от выбранной закладки. Согласитесь, что заставлять пользователя постоянно бегать мышкой от одного края формы к другому жестоко, а именно так получится, если использовать штатный механизм закладок.
Сразу определимся, что переключение наших закладок будет работать так же, как и штатный механизм, т.е. через включение-выключение нужных слоев. Для лучшей внедряемости кода мы даже будем вызывать для переключения закладок предопределенную процедуру ПриВыбореЗакладки().
Итак, для реализации нам понадобится на форме большая недоступная кнопка, которая будет служить рамкой для места, которое изменяется при переключении закладок. Недоступность кнопки, как вы понимаете, необходима, чтобы избежать ее нажатия, если у пользователя вдруг «дрогнет рука». Собственно закладки будем так же реализовывать в виде кнопок. Они должны в порядке обхода стоять «выше», чем кнопка-основа, и частично перекрываться ею. Буквально на несколько пикселей. В конфигураторе должна получится картинка примерно такого вида как на рисунке 4.

Рисунок 4
 
Уже неплохо.
Теперь перейдем к обеспечению выделения активной закладки. Для этого на форму на стыке кнопок-закладок и кнопки-основы необходимо поместить текстовые реквизиты. При их размещении надо быть внимательным и осторожным. Именно на этом этапе нам понадобится точность, о которой говорилось выше. После размещения текстовых реквизитов установить для них флаг невидимости.
В итоге должно получится что-то похожее на рисунок 5. Порядок обхода при этом следующий: кнопки-закладки, кнопка-основа и реквизиты-ширмы.

Рисунок 5
 
Вы, наверное, уже заметили, что я постоянно напоминаю о правильном порядке обхода. О нем вообще лучше помнить всегда и настраивать для каждой формы вручную. Конечно, есть автоматический режим, и он неплохо работает на простеньких формах. Но если вы делаете большую солидную форму, то выставлять нужный порядок обхода вручную просто жизненно необходимо для нее.
Итак, нам остался последний шаг – написать программную поддержку созданной формы. Выглядеть это будет примерно так:
Перем ТекущаяЗакладка;

Процедура ПриВыбореЗакладки(НомерЗакладки, ЗначениеЗакладки)
	// здесь выполняются действия по переключению слоев
КонецПроцедуры

Процедура ВключитьЗакладку(НомерЗакладки)
	// деактивируем все закладки
	Форма.Основа.Видимость(0);
	Для инд = 1 по 3 Цикл
		Форма.ПолучитьАтрибут("Ширма"+инд).Видимость(0);
	КонецЦикла;
	// активируем нужную закладку
	Форма.Основа.Видимость(1);
	Форма.ПолучитьАтрибут("Ширма"+НомерЗакладки).Видимость(1);
	ТекущаяЗакладка = НомерЗакладки;
	// вызов штатного средства работы с закладками
	ПриВыбореЗакладки(НомерЗакладки, "Закладка"+НомерЗакладки);
КонецПроцедуры

Функция СостояниеФормы()
	Форма.ПолучитьАтрибут("Ширма"+ТекущаяЗакладка).Видимость(1);
КонецФункции

ТекущаяЗакладка = 1;
Здесь, как вы наверное уже заметили, используется функция «СостояниеФормы()», работа с которой уже упоминалась в статье.
Очевидно, что для переключения закладок необходимо просто на наших кнопках-закладках в поле «Формула» прописать вызов процедуры «ВключитьЗакладку()», указав при этом порядковый номер закладки. Не забудьте только, что номер закладки должен соответствовать номеру в идентификаторе реквизита-ширмы.

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

[наверх]