gifts2017

Как раскрасить контрагентов в отчетах за 15 минут

Опубликовал Александр Венгер (venger) в раздел Программирование - Работа с интерфейсом

Попросили меня как-то ввести «цветовую дифференциацию штанов» у контрагентов в базе 1С 7.7, да так, чтобы они и в печатных формах отчетов выводились соответствующим цветом. Например, чтобы можно было каких-нибудь «злостных» должников выделять красным, а особо важных – синим, а уже не актуальных – сереньким и т.п.
И если раскрасить формы списков справочника и организовать выбор цвета с формы элемента справочника не особо напряжно (с FormEx’ом), то с отчетами хотелось бы сделать так, чтобы не прилагать «титанических» усилий по переписыванию и дописыванию разнообразных отчетов, где фигурируют контрагенты. И поэтому, немного подумав, поступил так…

Тут я описываю скорее идею, чем ее конечную реализацию, да и применить ее можно не только к контрагентам, а и к другим справочникам, да и развить идею по функционалу, естественно, тоже есть куда. Итак, для начала, организуем выбор цвета контрагенту и раскраску форм списков, а затем уже перейдем к отчетам.

Качаем formex.dll, закидываем его в папку с базой, в процедуре ПриНачалеРаботыСистемы() глобального модуля пишем:

ЗагрузитьВнешнююКомпоненту("FormEx.dll");
Сервис = СоздатьОбъект("Сервис");
Сервис.ВключитьРаскраскуТаблиц();

Затем в справочник контрагентов добавляем новый числовой реквизит Цвет. И на форму элемента бросаем текстовый контрол с идентификатором тЦветШтанов и формулой: Лев("Цвет штанов:"+Форма.тЦветШтанов.Цвет(Цвет),12). И рядом добавляем кнопку для выбора цвета с формулой: ВыборЦвета(). А в модуле формы определяем эту функцию:

//------------------------------------------------------
Процедура ВыборЦвета()
   
Сервис=СоздатьОбъект("Сервис");
   
ВыбЦвет=Сервис.ВыбратьЦвет(1,Цвет);
    Если
ВыбЦвет=-1 Тогда
        Возврат;
    КонецЕсли;
   
Цвет=ВыбЦвет;
   
Записать();
КонецПроцедуры 
// ВыборЦвета
//------------------------------------------------------

Получим результат при нажатии на кнопку выбора цвета, как на рисунке 1.

Рис. 1

Рисунок 1

И теперь, в формы списков все этого же справочника добавляем новый столбец (невидимый) в начало с заголовком FormEx_ПланРаскраски и формулой: "(FONT["+Цвет+"])". Как на рисунке 2.

Рис. 2

Рисунок 2

Собственно, назначение и хранение цветов для контрагентов, и раскраску их в списках мы организовали, можем полюбоваться (см. рис. 3).

Рис. 3

Рисунок 3

А вот теперь перейдем к отчетам. Объявим в глобальном модуле переменную:

Перем глТзРаскраскиТаблиц;

И в теле глобального модуля определим ее:

глТзРаскраскиТаблиц=СоздатьОбъект("ТаблицаЗначений");
глТзРаскраскиТаблиц.НоваяКолонка("Адрес","Строка");
глТзРаскраскиТаблиц.НоваяКолонка("Цвет","Число");

И допишем в глобальный модуль три простенькие функции:

//------------------------------------------------------
Функция глЗаписатьСтрокуТзРаскраскиТаблиц(Т,Расшифровка) Экспорт
    Попытка
       
Цвет=Расшифровка.Цвет;
       
ТекСтрока=1+Т.ВысотаТаблицы();
       
Адрес="R"+ТекСтрока+"C1:R"+ТекСтрока+"C"+Т.ШиринаТаблицы();
       
глТзРаскраскиТаблиц.НоваяСтрока();
       
глТзРаскраскиТаблиц.Адрес=Адрес;
       
глТзРаскраскиТаблиц.Цвет=Цвет;
    Исключение
    КонецПопытки;
    Возврат
Расшифровка;
КонецФункции   
// глЗаписатьСтрокуТзРаскраскиТаблиц
//------------------------------------------------------

//------------------------------------------------------
Процедура глОчиститьТзРаскраскиТаблиц() Экспорт
    Попытка
       
глТзРаскраскиТаблиц.УдалитьСтроки();
    Исключение
    КонецПопытки;
КонецПроцедуры 
// глОчиститьТзРаскраскиТаблиц
//------------------------------------------------------

//------------------------------------------------------
Процедура глРаскраситьТаблицу(Т) Экспорт
    Попытка
       
глТзРаскраскиТаблиц.ВыбратьСтроки();
        Пока
глТзРаскраскиТаблиц.ПолучитьСтроку()=1 Цикл
           
Область=Т.Область(глТзРаскраскиТаблиц.Адрес);
           
Область.ЦветТекста(глТзРаскраскиТаблиц.Цвет);
        КонецЦикла;
    Исключение
    КонецПопытки;
   
глОчиститьТзРаскраскиТаблиц();
КонецПроцедуры 
// глРаскраситьТаблицу
//------------------------------------------------------

А теперь берем, ну, например, отчет взаиморасчеты. Ищем там процедуру Сформировать() - ту, к которой «привязаны» кнопки «Ок» и «Сформировать» в форме отчета. И в начало этой процедуры (после объявления локальных переменных, конечно) прописываем вызов очистки ТЗ раскраски:

// Это вызов нашей функции
глОчиститьТзРаскраскиТаблиц();

// Это создание/очистка таблицы отчета перед
// формированием и выводом отчета
// Это уже было, т.е. добавлять это не надо
Если (ТипЗначенияСтр(Т) <> "Таблица") ИЛИ (Обновить = 0) Тогда
   
Т = СоздатьОбъект("Таблица");
Иначе
   
Т.Очистить();
КонецЕсли;

Потом находим показ таблицы отчета и перед ним прописываем вызов процедуры раскраски:

// Это вызов нашей функции
глРаскраситьТаблицу(Т);

// Это показ результирующий таблицы отчета
// Это уже было, т.е. добавлять это не надо
Т.Показать("Взаиморасчеты с контрагентами","");

И самое главное, переходим к таблице и в расшифровку ячеек, где выводятся контрагенты, вместо старой расшифровки прописываем такую формулу (допустим в расшифровке стояло «Запрос.Контрагент», а переменная типа «Таблица» в модуле формы отчета называется «Т»):

глЗаписатьСтрокуТзРаскраскиТаблиц(Т,Запрос.Контрагент)

Т.е. примерно как на рисунке 4.

Рис. 4

Рисунок 4

Теперь запустив этот отчет, наблюдаем картину, как на рисунке 5.

Рис. 5

Рисунок 5

Идея проста, ТЗ раскраски имеет две колонки: адрес области таблицы формата RnCn, которой нужно задать цвет текста; и цвет, который нужно задать этой области. Перед началом формирования отчета очищаем ТЗ для раскраски. В процессе вывода секций, значения расшифровок ячеек вычисляются, а значит и строки в ТЗ для раскраски добавляются. А перед показом, но после вывода, пробегаем по строкам ТЗ для раскраски, и записанные адреса раскрашиваем соответствующим цветом, после чего опять, на всякий случай, очищаем ТЗ раскраски. И собственно уже после этого показывается раскрашенная таблица отчета пользователю. Используем расшифровку ячейки отчета, потому, что иногда в самом тексте ячейки может быть текстовое представление контрагента, например, а не сам элемент справочника.

Поправив подобным образом все необходимые отчеты, мы и пришли к цели, «малой кровью» и без особых напряжений.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Дмитрий Литовченко (kompas-dm) 06.12.10 13:47
Аккуратно и доходчиво для многих разработчиков. Однозначно +
2. Епрст (Ёпрст) 06.12.10 14:36
Такая раскраска отчетов подходит только для укр конф.
В российских всё обезличено в отчете.
3. Александр Венгер (venger) 06.12.10 15:02
4. Дмитрий Литовченко (kompas-dm) 06.12.10 16:58
(2) Приехали..., причем здесь конкретная конфа м раскраска :?:
5. Brr (brr) 06.12.10 17:53
Для выбора цвета не обязательно использовать внешнюю компоненту. Перейти к форме Контрагента по двойному клику по ячейке теперь не удастся. Единственно где оправдано применение формекса в этом примере - список элементов справочника.
6. Епрст (Ёпрст) 07.12.10 09:17
(3) тем, что нет в ней Запрос.Контрагент в выражении, тем , что не можешь ты просто так написать в расшифровку ФункцияРасшифровки(ТЗ, траляля).
Все группировки выводятся динамически.
И тебе придётся, как минимум, красить нужную ячейку после вывода секции (что и сделано в типовых в некоторых отчетах), определяя тип и вид выводимого значения (или смотреть, что за группировку выводим).

(4) Прежде чем писать, думай хоть иногда.
Тем, что приведена методика для конкретной конфы.
7. Епрст (Ёпрст) 07.12.10 09:22
+6 но техническая реализация в даном примере - это вообще семечки, по сравнению с главной проблемой - "ручной" раскраской клиентосов.

Представляю себе картину - сидит девочка и каждый день "руктями красит" элементы справочника - васю..петю синим, маню федю зеленым.
И таких клиентосов пара тыщ.
Даже, если она будет их красить обработкой, ей придётся это делать как минимум, каждый день, как максимум - раз в час, чтоб актуальность раскраски была всегда.
В общем, не комильфо.
8. Александр Венгер (venger) 07.12.10 11:24
(5) > Перейти к форме Контрагента по двойному клику по ячейке теперь не удастся.

Кто тебе такую глупость сказал? Посмотри что функция глЗаписатьСтрокуТзРаскраскиТаблиц возвращает.

(6) > И тебе придётся, как минимум, красить нужную ячейку после вывода секции

Ты, по моему, не внимательно читаешь, после вывода секции и раскрашивается, по сути. А определение типа идет автоматом, попытка-исключение в функции глЗаписатьСтрокуТзРаскраскиТаблиц для этого и существует.

(7) > по сравнению с главной проблемой - "ручной" раскраской клиентосов

И нафига в описании идеи описывать добавление действия установки цвета в групповую обработку контрагентов? Я ж писал, что в центре внимание идея "малой кровью" раскрасить таблицы отчетов, а не долгая нудная статья, как я еще то дописал и это. А давай еще будем говорить, что хотелось бы фильтры в отчетах по цветам тоже сделать, кто ж мешает, я описал идею раскраски табличных форм, причем, если внимательно вникнешь, учитывающую все Ваши "поверхностные замечания", а развивать удобство использования цвета в базе уже можно сколько угодно, никто ж не мешает.

Опять же, можно раскрашивать не цвет текста, а фон, а можно и то и другое, естественно тогда функционал можно развить дальше, можно ввести еще не ракраску всей строки, а ввести в глЗаписатьСтрокуТзРаскраскиТаблиц еще параметр номер столбца и формировать адрес области - одну ячейку, у меня в реальной базе так, чтобы раскрашивалась только ячейка, а не вся строка.

В общем, вникайте внимательно, прежде чем ... "говорить";-)
9. Александр Венгер (venger) 07.12.10 11:28
(7) > Даже, если она будет их красить обработкой, ей придётся это делать как минимум, каждый день, как максимум - раз в час, чтоб актуальность раскраски была всегда.
В общем, не комильфо.

Ты не понял, вопрос не как задавать цвет контрагенту, а как раскрашивать таблицы отчетов;-) А как и откуда определять цвет контрагента - это второе дело, для примера удобнее было описать простое хранение в поле справочника, а можно хоть от долгов контрагента плясать, долг больше мильона - красный и т.д.;-)

Стареете, господа;-)
10. Brr (brr) 07.12.10 11:28
11. Епрст (Ёпрст) 07.12.10 11:32
(8) Ты типовые конфы видел вообще в глаза когда нить ?
Россейские ?
Там не получится запихать в ячейку свою расшифровку.
12. Александр Венгер (venger) 07.12.10 11:35
(11) Я могу развернуть сейчас, но давай проще, что в расшифровке идет там? Сразу сейчас и выясним, если в российских не пройдет, то я без проблем напишу, что это только для украинских.
13. Епрст (Ёпрст) 07.12.10 11:37
(9) Ну -ну.. у нас в базе > 5000 предлагаешь руками менять это поле ?
+ что считать долгом , если у клиентоса есть отсрочка платежа ?
Это ка минимум, определение текущего долга в данный момент времени, как максимум - определение только просроченного долга, ибо именно его клиентос должен оплатить в данный момент.

Да и техническая реализация через Расшифровку, да еще и в ТЗ скидывать - это вообще прошлый век.
Когда достаточно было написать так, и привет :

Таб.ВывестиСекцию(....)
Если <условие> Тогда
  Таб.Область(Таб.ВысотаТаблицы(),1,Таб.ВысотаТаблицы(),1).Цвет(<нужный>);
КонецЕсли
14. Александр Венгер (venger) 07.12.10 12:09
(13) > Ну -ну.. у нас в базе > 5000 предлагаешь руками менять это поле ?

Я предлагаю определять цвет контрагента (хранить ли в поле или каким-либо другим способом) так, как необходимо и удобно в каждом конкретном случае, иначе у тебя получается, что и раскраска списков FormEx'сом бесполезна;-) Я предлагаю способ раскраски отчетов, а не способ хранения цвета;-)

(13) > Да и техническая реализация через Расшифровку, да еще и в ТЗ скидывать - это вообще прошлый век.

А нафига мне лазить по отчетам (он же не один в конфе), в том числе и самописным, дописанным кем-то в типовой, и выискивать вывод нужных секций и разбираться с тем, будет ли еще присоединяться секция, например, или пойдет новая строка и т.д. и т.п.?
Да еще выискивать кто и где там контрагент, чтобы тоже условие прописать и т.д. и т.п., проделывать кучу действий в каждом отчете, если я сразу перешел на таблицу отчета и проставил в паре ячеек (а обычно вообще в одной) расшифровку и вперед? Т.е. с каждым отчетом проделываются однотипные простые и понятные действия и вникать в код отчета мне не нужно, что проще и удобней мне как разработчику в данном случае, так что прошлый век - это преждевременно;-)
15. Епрст (Ёпрст) 07.12.10 12:17
venger пишет:
иначе у тебя получается, что и раскраска списков FormEx'сом бесполезн


Еще бы!
Такое разделение клиентосов (по долгам) в таком виде - это полный пэ..
Нужно автоматизировать, а не лишнюю работу кому-то скидывать.
Вот у тебя, кто будет раскрашивать клиентосов ?

:)))
16. Александр Венгер (venger) 07.12.10 12:29
(15) У меня все проще, раскрашивать планируют только небольшое кол-во, относительно общей массы, и по особому указанию сверху;-) А раскрашивать будут менеджера отвечающие за свои группы контрагентов. Т.е. тут скорее "выделение" некоторых контрагентов из общей массы будет, чем тотальная раскраска всех.
17. ips 09.12.10 13:21
Господа! Если есть желание - помогите решить подобную задачу. Мне необходимо при подборе товара выделить цветом ячейку с остатками, чтобы, например, видеть нулевой остаток красным цветом и т.д. Буду очень признателен за помощь. В программировании я пока не спец, но кое-что под себя уже "заточил" в формах и отчётах.
18. Алевтина Охотникова (gilant) 10.12.10 09:40
Всё замечательно!
А как прописать в форме диалогов документов, раскрашивание строк с цветноштанным контрагентом?
19. Алевтина Охотникова (gilant) 11.12.10 00:50
Не дождался ответа,сам разобрался.
20. Александр Венгер (venger) 20.12.10 13:33
(19) Прально сделал;-)

З.Ы. Только вернулся с Карпат, вот и молчал по этому...
21. Михаил Подложнюк (ivanbonus) 05.10.11 07:37
Радость от установки была не долгой, всё хорошо работало устраивало и так далее, но после включения в рабочую базу терминал 25 пользователей стала вылетать такая надпись a required resource was unavailable и делался корявый интерфейс окон 1с пока не закроешь её и не зайдешь заново, может автор в курсе сей проблемы.
22. Александр Венгер (venger) 06.10.11 10:47
(21) А внешние компоненты свежие? Возможно там лежат старые? И при каких действиях/событиях это происходит?
23. Кирилл Ермошин (lafaaadka) 20.12.11 15:22
А такое есть для 8ки? УТ мне надо расскрасить отчет по поставщикам.
24. Дмитрий Веселов (Veduin) 15.02.12 12:39
Ну всеравно давольно таки интересный метод используется!
25. Алексей Пацура (formula76) 17.02.15 10:48
Спасибо! Очень доходчиво!
26. Евгений (marshal) 22.02.16 19:58
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа