Секретные технологии O-Planet (или автоматизация, на…) ЧАСТЬ 1

28.12.06

Сообщество - О жизни

Без сомнения, основным инструментом в работе с оптовым клиентом в программе «1С:Предприятие 7.7» становится окно подбора номенклатуры с количеством, которое устраивает абсолютное большинство пользователей кроме тех, у кого на складе находится до нескольких десятков тысяч номенклатурных позиций...
ЧАСТЬ 1. Техническая

Фирма, занимающаяся оптовыми продажами. Если учет автоматизирован, то все выглядит примерно так: клиент набирает товар, ему выписывается накладная, оплатив которую, можно отправляться на склад. Без сомнения, основным инструментом в работе с оптовым клиентом в программе «1С:Предприятие 7.7» становится окно подбора номенклатуры с количеством, которое устраивает абсолютное большинство пользователей кроме тех, у кого на складе находится до нескольких десятков тысяч номенклатурных позиций. Поскольку «1С:Торговля и склад» делает полный расчет остатка товаров по складу при открытии подбора, то в связи с этим на медленных компьютерах может возникнуть неуместная пауза в работе. «1С:Предприниматель» поступает еще «оригинальнее», рассчитывая остаток товара в реальном времени по каждой, отображаемой на экране товарной позиции. Представляете, как может «тормозить» обычная прокрутка списка товаров, ведь для расчета по каждой строке используется функция регистра «ПолучитьОстаток», а товаров в списке, как уже было сказано, несколько десятков тысяч?



Клиент, поставивший мне задачу ускорить процесс расчета остатков при подборе в 1С:Предприниматель, на тот момент обладал компьютерами на базе процессоров Celeron 1000, а в его базе находилось, без малого, 35000 товаров, поэтому, между переходами с одной строчки на другую в окне подбора, пауза возникала в полторы секунды, когда маркер уходил за границу видимого списка товаров, и на экране появлялась новая строка. Задача, фактически, могла быть перефразирована так: научить программу делать то, чего она делать не может по определению. Я люблю такие задачи.

Вариант переделки «Предпринимателя» в «Торговлю» я исключил сразу же, потому что пауза в минуту в начале подбора при присутствующем клиенте также никого не устраивала. Поддерживать в памяти актуальные итоги по остаткам номенклатуры для сервера с 256 МБ оперативной памяти, на котором висело еще пять компьютеров, сами понимаете, было бы жестоко. Требовалось нетривиальное решение.

Следует вспомнить об одной замечательной способности текстового поля на форме выводить на экран результат работы какой-либо функции, если эту функцию вписать в поле «Формула» окна текстового реквизита формы. При этом, значение функции всякий раз будет пересчитываться, когда на форме что-либо изменяется, например, когда меняется текущая строка в списке. Эту возможность я и использовал в собственном подборе.

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

В таком раскладе решение становилось делом техники. В форме списка я запустил в фоновом режиме накрутку «счетчика покоя», который сбрасывался в момент смены текущей строка в списке товаров. Если же этот счетчик достигал определенного значения, то предполагалось, что оператор нашел то, что ему нужно, и пора показывать остатки по товарам, которые реально видны на экране, а это – не 35000, а всего лишь несколько десятков. Вы спросите, как получить список этих нескольких десятков товаров? Очень просто, если воспользоваться замечательной возможностью платформы 7.7, вставлять в поле «Формула» окна настройки свойств чего-либо рассчитываемую on-line функцию. В версии 8.0, к сожалению, эта возможность исчезла.

Итак, я в колонке «Остаток» списка товаров, в поле «Формула» вписал вызов некой функции: «ПолучитьОстаток(1)». Интерес составляло то, что при перерисовке списка товаров, скажем, в 30 строк, эта функция рассчитывалась ровно 30 раз, по разу для каждой строки, и каждый раз внутри функции текущей считалась та строка, для которой она рассчитывалась. Разве это не то, что мне было нужно?

Кто не понял, попробуйте сделать следующее:


А функцию «ПолучитьОстаток» определите так:

Функция ПолучитьОстаток()
   Сообщить(ТекущийЭлемент());
   Возврат «»;
КонецФункции


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

// Таблица рассчитанных остатков, пополняемая в процессе работы.
// Имеет колонки «Номенклатура» и «Количество»
Перем ТаблицаОстатков; 

// Список новых товаров, по которым остатки предполагается расчитать
Перем НовыеТовары; 

// Вспомогательные переменные
Перем БылНовыйТовар, БылЭлемент, Счетчик;


Функцию «ПолучитьОстаток» я определил примерно так:

Функция ПолучитьОстаток()
	Переем Стр;
// Получаю товар из текущей строки
	ТекТовар= ТекущийЭлемент();

// Ищу, есть ли этот товар в рассчитанных ранее остатках
	Если ТаблицаОстатков.НайтиЗначение(ТекТовар,Стр,"Номенклатура")=0 Тогда   
// Остатка по тек. товару рассчитано ранее не было … 

// Для группы остаток рассчитывать не нужно
		Если ТекТовар.ЭтоГруппа()=1 Тогда
		    Возврат "";
		КонецЕсли;

// Добавляю товар в список товаров, по которым еще предстоит рассчитать остатки
		Если НовыеТовары.НайтиЗначение(ТекТовар)=0 Тогда
			НовыеТовары.ДобавитьЗначение(ТекТовар);

			// Сбрасываю счетчик и обновляю форму, говорю, что был новый товар
			Счетчик=0; 
			Форма.Обновить(1);

			// Включаем режим накрутки счетчика
			БылНовыйТовар=1;
		КонецЕсли;    
		Остаток="...";
	Иначе
// Остатка по тек. товару уже был рассчитан ранее …
		Остаток= ТаблицаОстатков.ПолучитьЗначение(Стр,"Количество");
	КонецЕсли;
	
	Возврат Остаток;
	
КонецФункции // ПолучитьОстаток


Фактически, в наш алгоритм осталось добавить только звено расчета остатков по товарам в списке «НовыеТовары». Для этого на форму помещаем текстовое поле, в формулу которого вешаем функцию «РасчетОстатков».



Разумеется, эта функция должна сработать не сразу.

Функция РассчетОстатков()

	// Если на экране есть товар, по которому остатки не рассчитаны
	Если БылНовыйТовар=1 Тогда
		// Тупо плюсуем счетчик
		Счетчик=Счетчик+1;

		// Сменилось положение маркера в списке товаров, значит 
// идет прокрутка и счетчик надо сбросить 
		Если БылЭлемент<>ТекущийЭлемент() Тогда
			Счетчик=0;
			БылЭлемент=ТекущийЭлемент();
		КонецЕсли;

	КонецЕсли;

	// Если счетчик достиг критического значения, то 
// рассчитываем остатки по списку «НовыеТовары»,
// добавляя их в таблицу «ТаблицаОстатков»
Если Счетчик=30 Тогда
		
		РасчитатьОстатки();

		// Список новых товаров очищаем
		НовыеТовары.УдалитьВсе();

		// Отключаем режим накрутки счетчика, счетчик сбрасываем
		БылНовыйТовар=0;
		Счетчик=0;

	КонецЕсли;

	// Если включен режим накрутки счетчика, то не забываем обновлять постоянно форму
	Если БылНовыйТовар=1 Тогда
		Форма.Обновить(1);
	КонецЕсли;	

// На форме можно отражать состояние счетчика до начала расчета остатков
	Возврат ?(Счетчик=0,"Ок",Окр(Счетчик*100/30,0,1));
КонецФункции


Задача решена полностью.

См. также

О жизни Россия Бесплатно (free)

Данная статья сугубо для раздела «О жизни», но может оказаться полезна многим членам сообщества. Все описанное ниже соответствует актуальному российскому законодательству на момент публикации статьи. У вас нет и в ближайшее время не предвидится детей возрастом до 1.5 лет? Вспомните о родственниках / друзьях / коллегах / знакомых, у которых они есть, и отправьте ссылку на эту статью — она может быть им чрезвычайно полезна. Распространите среди жильцов вашего ЖЭКа, как говорилось в одном классическом произведении. Помните, что, ставя плюсы к статье, вы поддерживаете её автора!

01.07.2024    5341    madonov    47    

51

О жизни Linux Системный администратор Программист Платформа 1С v8.3 Россия Бесплатно (free)

Использование Linux в качестве основной ОС для программиста 1С, возможно ли это? Решил поделиться личным опытом работы перехода на эту систему. В статье моя история без технических деталей максимально простым языком. И, спойлер, да, жизнь на Линуксе для разработчика 1С возможна и с каждым годом становится всё комфортней. Статья рассчитана на людей, с Линуксом не знакомых, специалистов прошу не кидаться помидорами.

16.05.2024    5735    soulner    33    

47

О жизни Россия Бесплатно (free)

Подводим итоги работы в 1С за 2023 год. Все о вас: 4 подробных раздела с цифрами, графиками и ужасными цветами диаграмм (должна же где-то быть стабильность).

08.02.2024    28135    Neti    85    

121

О жизни Бесплатно (free)

В процессе написания статей на тему Идеальное место работы ЗУПера нужен аргументированный текст про адекватного работодателя. Информации получилось много, поэтому выделю в отдельные 2 статьи. Рассмотрим все недостатки работодателей от момента собеседования до момента увольнения. Все этапы, как всегда, подкреплены реальными случаями из моего опыта.

22.01.2024    5559    biimmap    67    

76

О жизни Конфигурации 1cv8 Бесплатно (free)

В процессе написания статей на тему Идеальное место работы ЗУПера нужен аргументированный текст про адекватного работодателя. Информации получилось много, поэтому выделю в отдельные 2 статьи. Рассмотрим все недостатки работодателей от момента собеседования до момента увольнения. Все этапы, как всегда, подкреплены реальными случаями из моего опыта.

16.01.2024    7193    biimmap    100    

79

О жизни Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и Управление Персоналом 3.x Бесплатно (free)

Импортозамещение увеличило потребность в архитекторах, аналитиках, разработчиках 1С, в т.ч. по ЗУП. Все их ищут всеми возможными способами, но не могут найти и не знают, чем же их завлечь к себе!? Давайте разберёмся в этом вопросе!

27.11.2023    5786    biimmap    52    

74

О жизни Сообщество Бесплатно (free)

Прочитав название публикации, мысль возникает о свадьбе... Но речь не об этом!

25.08.2023    3215    biimmap    24    

51
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. O-Planet 6444 09.01.07 17:55 Сейчас в теме
А комменты черкнуть? :(
2. Bobak 206 10.01.07 09:30 Сейчас в теме
Прикольно! +1
Я, когда решал подобную проблему, не додумался до формулы в колонке :(. А так бы еще красивше получилось :). Ну теперь буду знать.
3. O-Planet 6444 11.01.07 21:33 Сейчас в теме
Ты еще, вероятно, не знаешь про возможность включения функций в тексты запросов. Это - прикольнее даже ))
4. Bobak 206 12.01.07 07:27 Сейчас в теме
>Ты еще, вероятно, не знаешь про возможность включения функций в тексты запросов. Это - прикольнее даже ))

Шутка не дошла :(.

Не очень понятно назначение
Код
       Если БылЭлемент<>ТекущийЭлемент() Тогда
         Счетчик=0;
         БылЭлемент=ТекущийЭлемент();
      КонецЕсли;
Показать полностью

Получается что, если я прокручиваю список клавиатурой, то остатки никогда не будут расчитаны!?
Да и зачем
Код
Счетчик
Показать полностью
? Я прокручиваю список и пока не выйдет новых 30 элементов, я не увижу остатки!?
По моему
Код
Счетчик
Показать полностью
лишний. А для исключения "подвисания" при быстрой прокрутке лучше сделать паузу перед расчетом.
5. Bobak 206 12.01.07 07:30 Сейчас в теме
Упс, глюк небольшой. Повторяю вторую часть.

Да и зачем Счетчик ? Я прокручиваю список и пока не выйдет новых 30 элементов, я не увижу остатки!?
По моему Счетчик лишний. А для исключения "подвисания" при быстрой прокрутке лучше сделать паузу перед расчетом.
6. O-Planet 6444 12.01.07 08:22 Сейчас в теме
> Шутка не дошла :(

Код
Функция ХорошийТовар(Тов)
   Возврат ?((Тов.ЭтоГруппа()=0) и (Найти(Тов.Наименование,"чебурашка")>0),1,0);
КонецФункции

...

ТекстЗапроса="
|Тов=Справочник.Номенклатура.ТекущийЭлемент;
|Группировка Тов;
|Условие(ХорошийТовар(Тов)=1);
|";

...
Показать полностью

7. O-Planet 6444 12.01.07 08:27 Сейчас в теме
> Не очень понятно назначение
Счетчик, вообще-то, накручивается независимо от прокрутки списка по функции, прописанной в формуле строкового поля. Обрати внимание, что в конце функции "РасчетОстатков" стоит команда обновления формы. Это, по сути, таймер и есть. Короче, если ты в списке ничего не делаешь, то счетчик успешно доходит до 30 и производится расчет остатков. Если же счетчик еще не дощел до 30, и ты в списке сдвинул маркер, то есть, сменил ТекущийЭлемент, то счетчик сбросился и снова ждет, пока не появится пауза, позволяющая ему дойти до 30.
8. Bobak 206 12.01.07 18:05 Сейчас в теме
Шутка все равно не дошла :).
Про эту шутку я знаю, правда ни разу не пользовался.
И все же прием описанной в этой статье гораздо прикольней :).

>Счетчик, вообще-то, накручивается независимо от ...
Дошло :). Реализация таймера средствами 1С :(.
Сбил с толку Счетчик. Если бы был замер времени, то было бы понятней и, по моему, правильней.
А то как то нехорошо, что время срабатывания зависит от быстродействия компьютера :).
Правда 1С умеет считать минимум секундами, если верить ЖКК :). Так что типовыми средствами не обойдешься :(.
В общем, наверное лучше не сделаешь.
9. O-Planet 6444 13.01.07 04:49 Сейчас в теме
> А то как то нехорошо, что время срабатывания зависит от быстродействия компьютера :).
В этом есть минус, но есть и плюс. Можно, к примеру, на каждой машине свой интервал установить...
10. Искренний 17.03.07 13:45 Сейчас в теме
ну насчет времени помоему вообще всё просто в данном случае и было бы понятней для юзера.
по поводу вообще решения. мне не нравится постоянное обновление формы... и то что ограничения количества строк для пересчета задаются платформой, а в коде нет ограничений.
а так, как обычно: работает, быстро - зачот.
11. wolfsoft 2421 17.03.07 17:48 Сейчас в теме
И как обычно есть фича :)
Пример глюка-фичи:
Структура справочника "Номенклатура":
------
Группа "1", в ней
Группа "2"
Элемент "3"
------
При первом открытии группы "1" курсор текущего элемента на группе "2", в остатке по элементу "3" выводит "...". После повторного закрытия-открытия папки "1" остаток выводится нормально.
12. O-Planet 6444 18.03.07 04:07 Сейчас в теме
Рабят! Ну я ведь не псих, чтобы весь код выводить! Это уже не статья будет, а мануал для программера. Там в реальной проге проверок у меня тьма и код в два раза объемнее. Сами уж доходите...
13. O-Planet 6444 18.03.07 04:08 Сейчас в теме
Кстати, ... при первом открытии - это не глюк...
14. wolfsoft 2421 18.03.07 20:55 Сейчас в теме
2 O-Planet: Да у меня-то все заработало ;) Я просто про этот "конкретный" код сказал. Чуть-чуть подправил и все нормально :)
ЗЫ: > Кстати, ... при первом открытии - это не глюк...
Не, не красиво два раза папку открывать, чтоб остатки увидеть, ИМХО :)
15. O-Planet 6444 19.03.07 03:29 Сейчас в теме
Заработало? Странно... :)
16. wolfsoft 2421 19.03.07 10:14 Сейчас в теме
Заработало - заработало, куда ж оно денется! :)
17. NewNick 15.04.07 20:56 Сейчас в теме
>Очень просто, если воспользоваться замечательной возможностью платформы 7.7, вставлять в
>поле «Формула» окна настройки свойств чего-либо рассчитываемую on-line функцию. В версии 8.0, к
>сожалению, эта возможность исчезла.

Уважаемый автор программы, придя по вашей ссылки для изучения методологических(и тд по списку) ляпов 8.0. Хочу задать вопрос почему в платформе 8.0 нельзя заменить реализованый в 7.7 функционал полем "Формула" при помощи события ПриВыводеСтроки?
18. O-Planet 6444 19.04.07 03:29 Сейчас в теме
В контексте статьи такая досадная утрата не была озоглавлена словом ляп. Я тут просто сравниваю 7.7 и 8.0. "ПриВыводеСтроки", вероятно, решит вопрос конвертации алгоритма из статьи в 8.0. но речь-то - не об этом. Я сетовал про то, что в 7.7 любое изменение на форме поля, таблицы, флажка, клик по кнопке, запускал волну обхода формы. и можно было решить вопрос "ПриИзмененииЧегоЛибо" очень просто: текстовым полем с формулой. В 8.0 такое простое решение уже не проходит. И не должно, собственно. Там вся логика постоения работы с платформой и объектами конфигурации иная. Я не говорю, в данном случае, что 8.0 хуже. нет, это более высокий уровень программинга, чем 7.7. Мой всдох - скорее ностальгический. Я помню, как в Borland C 3.11 мог составить программу на уровне винтиков. В Builder C++ 6.0 возможности несомненно шире, но вот ощущения контроля всего на низком уровне поэтому-то и не остается. Это - целая философия, что прогресс ведет к катастрофе. Когда становится меньше ручного труда, тогда утрачивается ощищение того, что ты часть этого мира.
19. Бубузяка 62 29.06.07 12:30 Сейчас в теме
Идея отловить "видимый" список хороша, зачет.
В 8 ке поможет событие списка "ПриПолученииДанных()", этого достаточно что бы получить состав выведенный строк.
20. d.snissarenko 152 26.09.07 14:26 Сейчас в теме
решение старо как мир, у меня с ТиС 8 используется, но зато подсказал людям которые не знают, я после 7ки перейдя в 8ку долго над этим парился, но в итоге все запихнул в один запрос и вывожу процедурой ПриПолученииДанных()
21. d.snissarenko 152 26.09.07 14:26 Сейчас в теме
ппс - плюсовать не буду - поскольку решение тривиальное
22. O-Planet 6444 27.09.07 03:50 Сейчас в теме
Оставьте свое сообщение