v8: Концепция минимального изменения конфигурации для легкого обновления
Разработка - Математика и алгоритмы
Структура статьи:
- Цель
- Концепция
- Объекты системы без четкого описания методики изменения
- Методики
Сразу оговорюсь, что изменение конфигурации по описанной ниже методике более трудоемка, но время, потраченное на этапе разработки с лихвой окупается при последующих обновлениях.
ЦЕЛЬ
Модификация конфигурации, находящейся на поддержке, с возможностью последующего «быстрого обновления».
КОНЦЕПЦИЯ ИЗМЕНЕНИЙ
- Минимальная правка кода в модулях конфигурации. Все требуемые изменения нужно выносить в общие модули или модули менеджеров новых объектов (справочников / регистров / обработок), логически связанных с вносимыми изменениями.
- Отказ от «непосредственного» изменения текстов запросов. Касается как запросов расположенных в текстах модулей, так и запросов-источников динамических списков.
- Отказ от изменения форм объектов на уровне конструктора форм. Использование только программного (при помощи написанного кода) способа. Речь идет не только о добавлении/изменении элементов форм, но и о добавлении реквизитов форм, событий элементов форм (и самой формы) и условного оформления форм.
- Максимальное использование подписок на события.
ОБЪЕКТЫ СИСТЕМЫ БЕЗ ЧЕТКОГО ОПИСАНИЯ МЕТОДИКИ ИЗМЕНЕНИЙ
- Изменение ролей
- Изменение функциональных опций
- Изменение состава реквизитов
- Изменение состава регистраторов
- Изменение состава общих команд
- Изменение схем компановки данных
МЕТОДИКИ
- Комментарии к изменениям. Считается хорошим тоном, а в случае изменения модуля, находящегося на поддержке являются обязательными комментарии с открывающимися и закрывающимися «тегами» к программному коду который вы внесли/модифицировали. Обычный минимум – это дата изменения и «ФИО» разработчика. Плюсом будет номер тикета или краткое описание изменений.
- Минимальная правка кода в модулях конфигурации. Руководствуемся «достаточным» минимумом изменений. Конечно, если Ваши изменения в объеме 1-3 строки, то не стоит для этого их выносить в отдельный модуль. В случае если код «большой» или он используется в нескольких местах, выносим его из тела модуля.
Все вызовы функций/процедур воспринимаем как некий «черный ящик» у которого есть параметры/источники данных (передаваемые или общие) на вход и результат на выходе. Если мы можем изменить входные параметры таким образом, чтобы «метод» вернул нам требуемый результат – меняем входные параметры (передаем их в нашу процедуру/функцию) и там их переопределяем. Если есть возможность изменить/дополнить данные на выходе – вызываем наш метод после. В случае невозможности «подменить» входные/выходные параметры принимаем решение: либо разбираемся-«осветляем» ящик и ищем «точку входа» в нем, либо пишем свой метод взамен текущего.
Результаты запросов, если есть сложность и нецелесообразность менять сам запрос (см. методику модификации запроса ниже) тоже можно переопределить/дополнить, выгрузив его в таблицу значений и потом в качестве источника модифицировать в своем запросе.
Если есть некая конструкция кода с условиями и циклами, результат которого вам «не подходит» после нее напишите свой и «переопределите» результат. Нужно ли комментировать исходный код зависит от его ресурсоемкости. Желательно его оставить «как есть».
Свои процедуры и функции можно располагать в новых общих модулях или менеджерах Ваших новых объектов. К примеру, если Вы создали справочник «Номенклатура клиентов» и в печатных формах Вам нужно модифицировать запрос таким образом чтоб вместо артикула номенклатуры компании выводился артикул клиента – процедуру модификации запроса целесообразней расположить именно в модуле менеджера справочника «Номенклатура клиентов».
По возможности стараемся не менять обработчики событий форм. О переопределении обработчиков событий, их «отключении» без модификации самих обработчиков и формы см. в разделе «Отказ от изменения форм объектов на уровне конструктора форм»
3. Отказ от «непосредственного» изменения текстов запросов. Часто используемым подходом к изменению текста запросов является «непосредственное» изменение запроса с закомментированными в нем «исходными» блоками. Основной недостаток такого подхода – при случайном или необдуманном использовании конструктора запросов «слетают» комментарии и «куски» закомментированного запроса от поставщика конфигурации. Другой способ – копирование и модификация исходного запроса целиком в своей процедуре и последующая подстановка нового запроса. В этом случае при обновлении конфигурации есть необходимость сверять запросы м/у собой – новый от поставщика старый от поставщика и измененный разработчиком. Причем, так как нужно сравнивать уже 3 текста, делать это приходится не средствами 1С, а сторонними программами, к примеру - KDiff3.
Предлагаемый подход направлен на сохранение первоначального текста запроса и «точечной» его модификации. Для этого находим требуемые задачей «точки входа» и функцией СтрЗаменить() меняем исходный текст запроса – вставляем необходимые условия, соединения, выбираемые поля. Небольшой пример для понимания (пример надуманный и очень простой, но помогает понять вышеописанный принцип):
ТекстЗапроса = «
|ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура»;
Нам нужно ограничить выборку записями, имеющимися в некотором регистре сведений и вывести некоторые значения из этого регистра
Добавим внутреннее соединение
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, «
| Справочник.Номенклатура КАК Номенклатура», «
| Справочник.Номенклатура КАК Номенклатура
|ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДляПримера КАК Пример
| ПО Номенклатура.Ссылка = Пример. Номенклатура»);
Вынесем в результат требуемые поля
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, «
| Номенклатура.Ссылка КАК Ссылка,», «
| Номенклатура.Ссылка КАК Ссылка,
| Пример.Поле1 КАК Поле1,
| Пример.Поле2 КАК Поле2»);
Таким образом, мы, сохраняя исходный текст на поддержке, при изменении его поставщиком (без кардинальных изменений), можем гарантировать обновление запроса поставщика без обдумывания наших изменений.
Немногим более сложна модификация предложенным способом пакетного запроса. Как вы уже догадались, пакетный запрос – это набор «одиночных» запросов. Нам остается разобрать пакет на отдельные запросы, изменить/подменить конкретный (ые) и собрать пакет запросов обратно. В УТ11 есть замечательные функции для этого «СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок()» и «СтроковыеФункцииКлиентСервер.ПолучитьСтрокуИзМассиваПодстрок()». Делителем строк будет являться символ «;».
Для динамических списков текст запросов меняем аналогично. В случае если динамический список использует реальную таблицу – меняем настройки динамического списка и подставляем текст запроса:
.УстановитьТекстЗапросаДинамическогоСписка_ЗаказНаПеремещениеСписок(Список);
Процедура УстановитьТекстЗапросаДинамическогоСписка_ЗаказНаПеремещениеСписок(Список) Экспорт
Список.ПроизвольныйЗапрос = Истина;
Список.ТекстЗапроса
= "ВЫБРАТЬ
| ЗаказНаПеремещение.Ссылка, ……
4. Отказ от изменения форм объектов на уровне конструктора форм. По моему мнению, самым проблемным в обновлении измененных конфигураций – это обновление форм. Решение, позволяющее упростить эту задачу – менять форму программным способом, т.е. использовать динамическое/программное изменение состава, отображения, поведения формы.
На программном создании элементов форм особо останавливаться не стоит, так как примеров и механизмов написано достаточно. Нужно только выбрать подходящий для себя. Я писал свой. Список добавляемых элементов хранится в макете. Вызов процедуры общего модуля происходит в процедуре ПриСозданииНаСервере(). При таком подходе я добавляю новые реквизиты в модифицируемый объект, прописываю вызов процедуры динамического создания элементов и добавляю в макет описание добавляемого реквизита. На все уходит не более 5 минут.
Реквизиты формы (те что нужны на форме только на момент ее существования и не должны храниться в базе) тоже создаю программно. Подход аналогичный подходу, используемый при создании элементов форм. При этом динамически созданный реквизит может являться источником (прописанным в пути) для динамического элемента формы.
Условное оформление тоже доступно для модификации программно. На момент написания статьи я еще не разработал более-менее внятного механизма по его «настройке» и просто прописываю в виде куска кода (конечно же, с вызовом в общем модуле).
Динамическое переопределение и добавление обработчиков событий формы.
Зачастую при модификации форм Вам, к примеру, на событие ПриИзменении нужно «добавить» обработку события. Обычно мы в форме определяем вызов метода «ПриИзменении» и уже в теле созданной процедуры описываем поведение. В этом случае при обновлении конфигурации у нас «распознаются» не только изменения модуля формы, но и изменения самой формы.
Мною разработан модуль «динамически подключаемых обработчиков событий» элементов форм и самих форм со следующим функционалом:
- Добавление обработчика события
- Удаление обработчика события
- Переоределение обработчика события с возможностью вызова оригинального обработчика до, после, либо возможность его отключить.
На практике на момент написания данной статьи мною разрабатывается конфигурация для крупной торговой компании, занимающейся поставкой инструментов, на базе УТ11. Формы справочников и основных документов товарооборота и планирования сильно доработаны. Добавлены реквизиты шапки, табличных частей, вычисляемые реквизиты форм, добавлены и переопределены обработчики событий форм и реквизитов. Блокируются строки в табличных частях товаров и многое другое. Всего не описать. Примечательно, что при всех этих изменениях в модулях измененных форм всего несколько вызовов процедур в процедуре «ПриСозданииНаСервере» и в случае динамически подключаемых событий по одному «шаблону-процедуре» на событие.
Данная статья не предполагает детального описания разработанного вышеуказанного механизма. В случае здорового интереса к нему готов написать отдельную статью с детальным описанием и выложить исходники с примерами использования модуля по созданию динамических реквизитов, элементов и подключаемых обработчиков.
5. Максимальное использование подписок на события. Собственно если есть возможность использовать подписку на событие – используйте.
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
См. также
Математика и алгоритмы Разработчик 1С 8.3 Абонемент ($m)
Данная внешняя обработка для платформы 1С:Предприятие реализует усовершенствованный алгоритм Левенштейна для вычисления схожести строк с учетом различных лингвистических особенностей русского языка. В отличие от классической реализации, этот алгоритм учитывает фонетические, визуальные и контекстные особенности набора текста.
1 стартмани
07.11.2025 7072 18 InFlach 17
Математика и алгоритмы Запросы Разработчик 1С:Предприятие 8 Бесплатно (free)
Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.
08.07.2024 9225 ivanov660 9
Математика и алгоритмы Разработчик 1С:Предприятие 8 1C:Бухгалтерия Россия Абонемент ($m)
На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.
1 стартмани
30.01.2024 17045 stopa85 12
Математика и алгоритмы Бесплатно (free)
Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.
19.10.2023 25317 user1959478 57
Математика и алгоритмы Разное 1С:Предприятие 8 1C:Бухгалтерия Россия Абонемент ($m)
Расширение (+ обработка) представляют собою математический тренажер. Ваш ребенок сможет проверить свои знание на математические вычисление до 100.
2 стартмани
29.09.2023 15775 maksa2005 8
Математика и алгоритмы Инструментарий разработчика Разработчик 1С:Предприятие 8 Россия Абонемент ($m)
Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.
1 стартмани
09.06.2023 25672 13 SpaceOfMyHead 20
Математика и алгоритмы Разработчик 1С:Предприятие 8 Бесплатно (free)
Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.
03.04.2023 17771 RustIG 10
Механизмы платформы 1С Математика и алгоритмы Разработчик 1С:Предприятие 8 Россия Бесплатно (free)
В статье анализируются средства платформы для решения системы линейных уравнений в 1С. Приводятся доводы в пользу некорректной работы встроенных алгоритмов, а значит потенциально некорректного расчета себестоимости в типовых конфигурациях.
23.11.2022 16664 gzharkoj 17
(1)(2) я постараюсь до 04.02.2013 написать статью по динамическому изменению форм. сложнее всего будет создать пример и хелповое описание ).
В качестве анонса: вчера дописал статью "v8.2 Управляемые формы: Динамические элементы формы и переопределяемые события или как изменить поведение и внешний вид управляемой формы программно без лишних хлопот ". Это статья по примеру реализации пункта "Динамическое переопределение и добавление обработчиков событий формы."
В данный момент статья на модерации. Как только она станет активной - сразу скину ссылку всем заинтересовавшимся.
Мы всегда несем ответственность за свои изменения. Более того, изменения стандартной конфы зачастую несут глобальный характер с переименованием и переписыванием кода целиком. Могу ссылаться только на свой опыт. А получилость так что при обновлении на новый релиз мне пришлось проверять и вылавливать "стационарные" изменения регистраторов, реквизитов, комманд и т.п. и ни одной проблемы с динамическими элементами/событиями сменой текстов запросов и тп. Может повезло-не спорю, но факт остается фактом.
Спасибо за рекоммендации
Если изменений в запросе много или изменился запрос в основной поставке,
то метод с СтрЗаменить() иногда только затрудняет обновление,
мне проще переопределять текст запроса ниже типового текста зароса.
Для динамического создании элементов форм так и не нашел удобного для меня инструмента,
который позволял бы делать это быстро и удобно..
Но в конфигурациях на УФ с этим стало попроще благодаря встроенным механизмам
А в остальном все указано верно и соответствует здравому смыслу и метод. рекомендациям 1с по этому вопросу )
Правда, маловато написано про формы.
На этом сайте присутствует замечательная статья
.
С первого раза идея, изложенная в статье, мне показалась сложной, но прочитав текст статьи 2 раза и код процедур, я осознал простоту и гениальность метода.
Теперь для изменения форм я использую такой подход:
1) Все доработки я делаю только на копиях форм. Т.е. если я меняю форму элемента или списка справочника, я всегда делаю копию оригинальной формы (например, script_ФормаЭлемента), устанавливаю ее основной, и только потом приступаю к доработке.
При обновлении, в разделе объединение и сравнение ... такой объект отобразится как измененный.
В свойствах такого объекта будет значиться, что изменена основная форма элемента.
Среди форм данного объекта появится "МОЯ" форма, а оригинальной формы не будет. Это значит что кроме моей формы, других изменений в объекте нет. Если же появляется и оригинальная форма, тогда становится понятным то, что поставщик внес свои изменения в данную форму и мы сможем увидеть отличия без наших доработок.
Далее принимаем решение, что проще? Перенести изменения в "Нашу" форму или скопировать обновленную, оригинальную форму и внести доработки повторно.
2) Элементы на форму я стараюсь поместить программно, но поскольку большинство моих конфигураций работают на обычных формах, такой подход не всегда реализуем или правильнее сказать, не всегда простой в реализации, но предпочтение я отдаю именно ему.
3) Это переопределение обработчиков событий элементов форм по, указанной в статье, методике.
по п1. решение, по моему скромному мнению, интересное и, как вариант, может применяться должно при очень больших изменения форм. но в этом случае мы отказываемся от поддержки такой формы, а как следствие и вызываемых методов общих модулей (1С часто грешат тем что перекидывают из модуля в модуль и меняют параметры написаннх методов).
Небольшое дополнение здесь: если вы используете платформу 8.2 последних версий то для того чтобы не переопределять основную форму в метаданных есть подписка на событие менеджера объекта "ОбработкаПолученияФормы" в которой можно переопределить вызов основной формы.
Буду рад прочитать статью ознакомиться с Вашей статьей и почерпнуть новые подходы, в чем я лично сомневаюсь.
Статья конечно не доработанна, но это не повод "так" о ней отзываться
(20)(22)(23)
Конечно же в статье я не рассматривал вопросы с простыми случаями, ситуации когда можно и нужно делать новые документы, либо возможность использования дополнительных реквизитов и сведений. Речь шла о том, когда у вас "нет выбора" либо нецелесообразно создавать новые объекты.
К примеру у вас есть Заказ поставщику и часть его строк связана к "примеру в поступлением" ч/з код строки (пример надуманный, но имеет место быть. конфа УТ11). И клиенту нужно чтобы: эти строки выделялись в таблице
каким либо цветом и система не давала удалить и менять эти строки. Не думаю что в этом случае целесообразно создавать новый документ или новую форму, которые поддерживать придется. В моем случае будут произведены след. изменения: 1. в процедуре ПриСозданииНаСервере в конце процедуры будут добавлены примерно такие вызовы.
//добавляем динамически реквизит формы
// прописанно в макете "ДинамическиеРеквизитыФорм" служебной обработки "Служебная"
ДинамическиеЭлементыКлиентСервер.СоздатьДинамическиеРеквизиты(ЭтаФорма);
//подключаем подписки на события
ДинамическиеЭлементыКлиентСервер.ПодключитьОбработчики(ЭтаФорма);
//применяем условное оформление
УсловноеОформлениеФорм.ЗаказФормаДокумента_ПрименитьУсловноеОформление(ЭтаФорма);
и еще 2 процедуры-шаблона обработчиков событий (я прописываю эти шаблоны в самом начале)
&НаКлиенте
Процедура ПодключаемыйОбработчик_ТоварыПередНачаломИзменения(Элемент, Отказ)
МассивИнструкций = ДинамическиеЭлементыКлиентСервер.ПолучитьИнструкцииПереопределаемыхОбработчиков(ЭтаФорма, "ТоварыПередНачаломИзменения");
Для Каждого Инструкция из МассивИнструкций Цикл
Выполнить(Инструкция);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ПодключаемыйОбработчик_ТоварыПередУдалением(Элемент, Отказ)
МассивИнструкций = ДинамическиеЭлементыКлиентСервер.ПолучитьИнструкцииПереопределаемыхОбработчиков(ЭтаФорма, "ТоварыПередУдалением");
Для Каждого Инструкция из МассивИнструкций Цикл
Выполнить(Инструкция);
КонецЦикла;
КонецПроцедуры
Дальнейшый код будет существовать вне "поддерживаемых" объектов системы.
Другой пример в документе с таблицей товаров рядом с количеством выводить колонку кратности указанного количества. т.е. если 10 шт. товара а основная упаковка 8 штук в кратности должно быть "1,25(8/16)" и эта строка подсвечивалась. Решается таким же набором изменений. только шаблонов будет не один а 3-4. Шаблоны меняются только наименованием и строковым параметром внутри процедуры.
Я готовлю конфу с примерами в которой приведу примеры использования мое подсистемы динамических объектров и событий
Нам, конечно, с одной стороны нужно добиться:
1. минимизации ручного переноса изменений в новые релизы
Но с другой стороны нам нужно:
2. обеспечить, чтобы все изменения надежно переносились в следующий релиз и надлежащим образом адаптировались к новому релизу, если есть такая необходимость.
Поэтому практику:
а) копирования семиэтажных запросов и изменения в них пары строчек
б) копирования типовых форм ради добавления пары элементов формы на них
и т.п. считаю вредной.
Если нам надо внести изменения в программу, то мы должны внести их так, что при обновлении было сразу видно что они, собственно, внесены, а также куда именно они внесены, и зачем они внесены.
Но пункт №3 лучше переименовать, назвать не "Отказ от «непосредственного» изменения текстов запросов.", а что-то вроде "Модификация запросов при помощи СтрЗаменить()".
Поясню: в статье, по сути предлагается отказ как от
1.непосредственного изменения,
так и от
2. копирования
и предлагается 3-ий метод - СтрЗаменить().
А сейчас из названия пункта №3 возникают ощущения, что предлагается именно отказ от неопосредственного изменения запроса.
Еще я б конечно поспорил насчет того, какой вариант лучше, 1 или 3, но про это уже было выше :)
Учту замечания при корректировке статьи, которая будет обязательно произведена на основаниии Ваших замечаний и других "высазавшихся".
Так же планирую дополнить статью - так сказать по максимуму заполнить "белые пятна"
А в СтрЗаменить один из минусов заключается в том, что заменяемых текст должен точно совпадать с куском текста запроса, вплоть до пробелов и прочих символов. Переформатируют текст - и пролетит СтрЗаменить мимо.
СтрЗаменить применительно к текстам запроса признаю только когда идет замена специально подготовленных меток, как это часто делается в типовых.
| //ДляРеглУчета СУММА(УчетЗатрат.ПостояннаяРазница) КАК ПостояннаяРазница,
| //ДляРеглУчета СУММА(УчетЗатрат.СтоимостьНУ) КАК СтоимостьНУ,
| //ДляРеглУчета СУММА(УчетЗатрат.КоличествоНУ) КАК КоличествоНУ,
|
| СУММА(УчетЗатрат.Стоимость) КАК Стоимость,
| СУММА(УчетЗатрат.Количество) КАК Количество
|
|ИЗ
| РегистрНакопления.УчетЗатрат%СуффиксРегл% КАК УчетЗатрат
|ГДЕ
| УчетЗатрат.Регистратор = &Регистратор
Используются для "ручной сборки" текста запроса.
В тех местах где они нам нужны их конечно не будет :)
ТекстЗапроса = "ВЫБРАТЬ &Поле ИЗ Справочник.Номенклатура ГДЕ &Условие";
а потом ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Поле", "Ссылка") и ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Условие", ?(ТолькоНепомеченныеНаУдаление, "НЕ ПометкаУдаления", "ИСТИНА")).
Такие метки не "слетают" при редактировании конструктором. имхо, их то как раз можно более-менее безобидно вставлять в "штатные" 1с-вские запросы.
А вообще идея состоит в том чтоб вообще не вносить никаких изменений в типовой запрос.
Что касается "они не "слетают" при редактировании конструктором" то зачастую, особенно в пакетных запросах 1С описывает наименование таблиц или вставляет комментарии и при использовании конструктора Вы теряете эти комменты.
думаю, только для простейших случаев.
Если же рассмотреть задачи модификации алгоритмов проведения (к примеру, в модуле менеджера УТ 11 - инициализировать документ), то такой подход только усложнит разработку и понимание. Проще вызвать переработанный текст запроса полностью.
Если Вы сами исправляете критическую ошибку 1С, то, наверное, правильнее править вносить изменения непосредственно в запрос с описанием типа "исправление такой-то ошибки" в надежде что ее поправят в послед. релизах. В этом случае Вы при объединении увидите и смодете проанализировать изменения на устранение оной.
А геморой именно в
Плюс к этому нужно будет как-то сверить уже 3 формы: старую от поставщика, новую от поставщика и новую с Ващими изменениями. Не очень приятное занятие, по крайней мере для меня.
Если еще принять во внимание тот факт, что 1С, зачастую, любить изменять формы до неузнаваемость, как это происходит на УТ 11 - я Вам не завидую.
В случае днамического добавления реквизитов на форму и динамических обработчиков максимум что произойдет - это ошибки при открытии формы о не найденных элементах формы с которыми очень легко разобраться.
Надеюсь я ответил на Ваш вопрос.
А можно для полноты в статью добавить ссылки, где есть примеры и механизмы?
Да, статью буду дописывать, так сказать, закрывать "белые пятна".
по моему механизму Вы можете ознакомиться, пройдя по ссылке .
В ней есть демо-конфигурация описанная в статье.
Жду Вашего мнения )
думаю пригодятся. ПЛЮС однозначно.
Вы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 170935
Создание 28.01.13 07:19
Обновление 28.01.13 07:19
Просмотры 42177
Загрузки 0
Рейтинг
181
Комментарии 57
Код открыт Не указано
Рубрики Математика и алгоритмы
Кому Разработчик
Тип файла Нет файла
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Не имеет значения
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Бесплатно (free)