Четверг, 23.11.2017, 06:14
Приветствую Вас, Гость
Главная » Статьи » В помощь программисту » Примеры программ на 1С версии 7.7

Удаление неиспользуемых товаров
1Cv7.7Хочу привести пример эффективного использования при программировании на 1С механизма запросов. Как известно, база данных 1С:Предприятия может храниться как в DBF формате, так и на SQL. Использование SQL позволяет эффективнее работать с большими объемами данных, особенно если в системе одновременно работает большое число пользователей. Но это не все преимущества SQL. Огромным плюсом системы 1С версии 7.7 является возможность создавать и выполнять SQL-запросы и использовать их результаты. В восьмой версии 1С эта возможность доведена до своего логического совершенства. В этой версии системы встроенный в 1С язык запросов полностью согласован с языком SQL. Внутренний язык запросов просто стал идентичен языку SQL. Но вернемся к версии 7.7 и тому примеру, который я хочу здесь рассказать.

И так задача: Удалить из справочника ТМЦ устаревшие и уже неиспользуемые товары. Среда - 1С:Предприятие версии 7.7. Способ хранения данных - SQL-база.

Тот, кто работал с большими базами товаров, хорошо знает, что в процессе работы справочник постоянно пополняется все новыми и новыми товарами. При этом часть товаров постепенно устаревает, становится не актуальным. Товары могут устареть, могут быть сняты с производства, заменены новыми. Но в справочнике все они остаются. Удалить такие товары вручную практически нереально. Найти среди тысяч товаров те, чкоторые точно уже не используются - задача архисложная. Поэтому и возникла задача создать программу, которая выполнит эту задачу автоматически. Очевидно, что для решения такой задачи нам нужно получить список товаров, у которых за какой то большой промежуток времени (в нашем случае ставилось условие за 1,5 последних года) отсутстует движение товаров и отсутствует конечный остаток. На самом деле условий там гораздо больше. Некоторые товары вносятся в справочник не для учета приходов и расходов. Есть товары, которые вносятся для расчетов, для составления спецификаций для будущих, еще не осуществленных закупок. Однако мы сейчас возмем упрощенный случай.

И так, на первый взгляд задача кажется простой. Я, создавая первый вариант программы так и сделал. Создал стандартный запрос к регистру остатков и выбрал в результатах запроса товары, для которых нулю равны приход, расход и остаток. Запустил программу и стал ждать результата. Через пол часа ожидания я понял, то такой способ задачи совершенно бесперспективен. Представьте себе - расчет движений по всем товарам из справочника, за полтора года! Да такой расчет будет длиться не один день. И все это время программа будет блокировать справочник ТМЦ и не давать другим пользователям работать. Для большого магазина, где работа идет каждый день с 8-00 до 23-00 без выходных и праздников, такая, фактически, остановка программы недопустима. Нужно было искать обходное решение. Естественно, я обратил свой взор к возможностям SQL.

И так, нам нужно выбрать товары, у которых отсутствует движение за выбранный период. Для учета движений товаров в программе 1С используется регистр "ОстаткиТоваров". В этот регистр записывается каждый приход и каждый расход для каждого товара. Регистр - это объект среды 1С. Физически регистр представляет из себя две таблицы в SQL базе данных. В одной таблице записываются все приходы и расходы. На каждый приход или расход в таблицу записывается одна строка (дна запись). Во второй таблице хранятся текущие остатки по каждому товару. Можно сделать запрос по таблице движений, который даст нам список всех товаров, для которых имеется хотя бы одна запись в этой таблице. Если при этом наложить условие, что бы поиск велся лишь среди записей дата и время которых попадает в требуемый период времени, мы получим список товаров, для которых есть движение. Для того, что бы получить список товаров без движения нужно усложнить запрос. Более сложный запрос должен выбирать все товары из справочника ТМЦ не помеченные на удаление и не содержащиеся в списке товаров, для которых есть движение, который мы должны получить при помощи вспомогательного запроса, полученного указанным выше способом.

Для того, что бы написать текст такого запроса необходимо сначала узнать имя таблицы в которой в вашей базе хранится регистр остатков, имя таблицы, где хранится справочник ТМЦ, а так же имена всех нужных нам полей. Вся эта информация хранится в специальном файле, который называется 1Cv7.DDS, который размещается в основной директории вашей информационной базы. Фал содержит описание структуры всех таблиц вашей базы. Для того, что бы найти описание регистра остатков, откройте файл 1Cv7.DDS в любом текстовом редакторе. Желательно в программе "Блокнот", или, например, в программе просмотра, которая запускается при нажатии клавиши F3 в программе totalcomander. Затем наберите в поиске слово "ОстаткиТоваров". В результате поиска мы найдем два описания таблиц для регистра с таким названием. В обоих описаниях слово "ОстаткиТоваров" втречаются два раза. Нас интересует второе из описаний, которое помечено как "Регистр (Дв.)". То есть, "регистр движения". Вот как выглядит это описание в моей базе:



#===============================================================================
#==TABLE no 192 : Регистр (Дв.) ОстаткиТоваров# Name |Descr |SQLTableNam |RecordLock
T=RA123 |Регистр (Дв.) ОстаткиТоваров |RA123 |


#-----Fields-------# Name |Descr |Type |Length |Precision
F=IDDOC |ID Document's |C |9 |0
F=LINENO_ |LineNo |S |0 |0
F=ACTNO |Action No |I |0 |0
F=DEBKRED |Flag Debet/Kredit |L |0 |0
F=SP124 |(P)Фирма |C |9 |0
F=SP125 |(P)Товар |C |9 |0
F=SP126 |(P)Склад |C |9 |0
F=SP127 |(P)ОстатокТовара |N |14 |5
F=SP128 |(P)ФлагУчета |N |1 |0


#----Indexes------# Name |Descr |Unique |Indexed fields |Type
I=PK_RA123 |of IDDOC+LineN |1 |IDDOC,LINENO_,ACTNO |1


Из этого описания мы можем узнать имя таблицы, в которой хранятся движения по регистру "ОстсткиТоваров". В моем случае таблица называлась "RA123". Для составления запроса мы должны найти поле, которое указывает на товар. Из описания видно, что это поле называется "SP125". И, наконец, нам понадобится дата создания каждой записи, что бы отобрать записи за нужный нам период. Но вот дата, как раз, в этой таблице не указывается. Однако, оказывается ссылка на документ, который произвел это движение. Ссылка на документ указывается в поле IDDOC. А дату придется извлекать из описания документа. Для хранения документов используется более сложная структура. Для каждого вида документа существует своя отдельная таблица. Но заголовки всех документов базы данных хранятся в одной общей таблице, которая называется "_1SJOURN". Описание этой таблицы вы так же можете найти в файле "1Cv7.DDS". Нас в этом описании будет интересовать поле с идентификационным кодом документа ("IDDOC") и поле, где хранится дата-время создания документа ("DATE_TIME_IDDOC"). Теперь мы можем перейти к составлению запроса. Ниже приведен фрагмент программы на 1С, который используя запрос получает список товаров, не имеющих движений за выбранный период времени:


Период, за который производится расчет движений определяется при помощи переменных "Дата1" и "Дата2". Эти даты, заданные в формате 1С программа преобразует в формат, принятый в запросах SQL. Для преобразования используется специально разработанная функция ПреобрДаты(). Вот текст этой функции:


Преобразование сводится просто к перестановке полей даты, номера месяца, года и добавление к номеру года двух первых значащих цифр ("20.."). Для получения имени таблицы, в которой хранится справочник ТМЦ используется специальный механизм препроцессора 1С. При выполнении запроса система 1С заменяет записи типа "$Справочник.ТМЦ" на имя соответствующей таблицы базы данных. В запросе используется условие "ISMARK=0" и "ISFOLDER=2". Поле ISMARK в таблице справочника ТМЦ - это пометка на удаление. Условие ISMARK=0 отбирает те записи, в которых нет пометки на удаление. Поле ISFOLDER определяет уровень вложенности элемента справочника. Данный справочник имеет допустимое количество вложенности групп элементов равным 2. Если элемент справочника - это группа, то значение ISFOLDER будет равно 0 или 1 (в зависимости от уровня вложения). Если же элемент - не группа, то его ISFOLDER равен 2. Условие ISFOLDER=2 позволяет отобрать простые элементы и отбросить группы.

Условие " ID not in (select...." означает "Выбрать элементы ID которых не входит в список являющийся результатом следующего далее запроса (текст этого запроса указан далее в круглых скобках). А текст этого запроса в круглых скобках как раз и есть запрос товаров для которых отсутствует движение. Это запрос по регистру RA123 ("ОстаткиТоваров"). Управляющее слово DISTINCT означает, что запрос должен выдать список всех значений поля SP125, без учета повторов. То есть, каждое значение поля в выходной таблице повторяется только один раз. Таким образом мы и получим список всех товаров, которые хоть раз представлены в регистре "ОстаткиТоваров". Условие "r.IDDOC = j.IDDOC" связывает таблицу регистра "ОстсткиТоваров", которой выше в том же запросе был присвоен алиас "r" и таблицу заголовков документов, которой там же, в запросе был присвоен алиас "j". Связать две таблицы необходимо для того, что бы для каждого движения из таблицы "ОстаткиТоваров" запрос правильно получал дату из соответствующего документа.

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

Готовая работающая программа выдает результат достаточно быстро. Если программа, написанная в лоб путем стандартного запроса за 8 часов работы обработала лишь 20% всего списка товаров, то приведенная выше программа со всеми дополнительными отборами и фильтрами полностью отрабатывает, в зависимости от размера базы и количества движений, от 2-3 секунд до 2-3 минут.
Категория: Примеры программ на 1С версии 7.7 | Добавил: bigman (01.10.2013)
Просмотров: 2552 | Комментарии: 1 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *: