Как не создавать каждый раз одинаковые документы!!! Прошу помощи
По теме из базы знаний
- Повышение качества разработки. Статья 3. Ошибки программы
- Отправка электронной почты с помощью локального почтового клиента из 1С, развернутой под удаленным рабочим столом
- Правила обмена больше не нужны
- Как искусственный интеллект помогает в работе с требованиями
- Неочевидные способы оценки эффективности аналитиков
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Не совсем понятно.
1) В подчиненном документе есть ссылка на исходный документ? Если есть тогда, сработает ВыбратьПодчиненные()
2) Точно также можно соорудить запрос по создаваемым документам с условием типа "ДокументОснование = МойДокумент"
1) В подчиненном документе есть ссылка на исходный документ? Если есть тогда, сработает ВыбратьПодчиненные()
2) Точно также можно соорудить запрос по создаваемым документам с условием типа "ДокументОснование = МойДокумент"
Ссылки нет, я беру все данные из ТЗ.
ОкУсл = СоздатьОбъект("Документ.ОказаниеУслуг");
ОкУсл.Новый();
ОкУсл.Контрагент=ТЗ2.Субконто1;
ОкУсл.Договор=ТЗ2.Субконто2;
ОкУсл.ДатаДок=Дата("КонецДня");
ОкУсл.ВариантРасчетаНалогов=ТЗ2.СтавкаНДС;
ОкУсл.НоваяСтрока();
ОкУсл.Услуга = ТЗ2.НаименДвижения;
ОкУсл.Сумма = ТЗ2.Приход;
ОкУсл.Цена = 1001;
ОкУсл.Количество = ОкУсл.Сумма/ОкУсл.Цена;
ОкУсл.НДС = ТЗ2.СтавкаНДС.Ставка;
ОкУсл.Всего = ОкУсл.Сумма;
ОкУсл.Записать();
ОкУсл.Провести("Программно");
И как теперь создавать условие не могу понять.. Нужно что найти документы за этот период и сравнить значения что ли?
ОкУсл = СоздатьОбъект("Документ.ОказаниеУслуг");
ОкУсл.Новый();
ОкУсл.Контрагент=ТЗ2.Субконто1;
ОкУсл.Договор=ТЗ2.Субконто2;
ОкУсл.ДатаДок=Дата("КонецДня");
ОкУсл.ВариантРасчетаНалогов=ТЗ2.СтавкаНДС;
ОкУсл.НоваяСтрока();
ОкУсл.Услуга = ТЗ2.НаименДвижения;
ОкУсл.Сумма = ТЗ2.Приход;
ОкУсл.Цена = 1001;
ОкУсл.Количество = ОкУсл.Сумма/ОкУсл.Цена;
ОкУсл.НДС = ТЗ2.СтавкаНДС.Ставка;
ОкУсл.Всего = ОкУсл.Сумма;
ОкУсл.Записать();
ОкУсл.Провести("Программно");
И как теперь создавать условие не могу понять.. Нужно что найти документы за этот период и сравнить значения что ли?
Нужно что найти документы за этот период и сравнить значения что ли?
Если не использовать выбор подчиненных документов, то да. Можно завести в оказании какой-нибудь реквизит (например "ВведенОбработкой") или задать специфический комментарий и отбирать по ним. Иначе придется сравнивать несколько значений (контрагент, договор, сумма, количество).
Но, думаю, самым оптимальным было бы завести в "ОказанииУслуг" реквизит "ДокументОснование", а в ТЗ добавить колонку "ДокОсн", куда записывать документ, но основании которого вводится оказание услуг. А потом при создании нового оказания услуг прописать
***********
ОкУсл.Новый();
ОкУсл.ДокументОснование = ТЗ2.ДокОсн;
а затем использовать ВыбратьПодчиненные();
Да там такое написано, разбираться и разбираться!! А если равнивать несколько значений (контрагент, договор, сумма, количество), то надо
ОкУсл.Новый();
ОкУсл2.Новый();
Если ОкУсл.ВыбратьПоНаименованию("Контрагент") = ОкУсл2.ВыбратьПоНаименованию("Контрагент") тогда прервать иначе продолжить;
Так что ли выполнить сравнение?
ОкУсл.Новый();
ОкУсл2.Новый();
Если ОкУсл.ВыбратьПоНаименованию("Контрагент") = ОкУсл2.ВыбратьПоНаименованию("Контрагент") тогда прервать иначе продолжить;
Так что ли выполнить сравнение?
Есть возможность добавить в ТЗ колонку "ДокОсн" и потом при записи значений в ТЗ дописать ТЗ2.ДокОсн = ТекДокумент (на основании которого будет вводится оказание услуг)? Тогда в комментариях оказания услуг можно записать
*****
ОкУсл.Новый();
------------
ОкУсл.Комментарий = ТЗ2.ДокОсн;
ОкУсл.Записать();
А затем смотреть, если при создании на основании ДокОсн есть документ ОказаниеУслуг с комментарием "ДокОсн", то не создавать или удалить и создать новый. Как-то так :)
*****
ОкУсл.Новый();
------------
ОкУсл.Комментарий = ТЗ2.ДокОсн;
ОкУсл.Записать();
А затем смотреть, если при создании на основании ДокОсн есть документ ОказаниеУслуг с комментарием "ДокОсн", то не создавать или удалить и создать новый. Как-то так :)
(12) допустим, что мы добавили в ТЗ колонку "ДокОсн", ок?
И создали минимум один раз документы ОказаниеУслуг с комментарием "ДокОсн". Тогда примерно так:
ОкУсл = СоздатьОбъект("Документ.ОказаниеУслуг");
СоздаватьДокумент = 1; //флаг, если нужно создавать новый документ
ОкУсл2 = СоздатьОбъект("Документ.ОказаниеУслуг");
ОкУсл2.ВыбратьДокументы(ДатаНачала, ДатаКонца);
Пока ОкУсл2.ПолучитьДокумент() = 1 Цикл
Если СокрЛП(ОкУсл2.Комментарий) = СокрЛП(ТЗ2.ДокОсн) Тогда //есть оказание услуг, введенное на основании ДокОсн
//если удаляем и создаем новый тогда
ОкУсл2.Удалить();
СоздаватьДокумент = 1;
//или если не создаем
Продолжить;
СоздаватьДокумент = 0;
КонецЕсли;
КонецЦикла;
Если СоздаватьДокумент = 1 Тогда
ОкУсл.Новый();
ОкУсл.Контрагент=ТЗ2.Субконто1;
******
ОкУсл.Всего = ОкУсл.Сумма;
ОкУсл.Комментарий = ТЗ2.ДокОсн;
ОкУсл.Записать();
Примерно так, код не проверял, но идея надеюсь понятна. Можно выборку документов с комментариями сделать заранее, как вариант в виде запроса, и записать все комментарии в еще одну ТЗ и затем искать в ней.
И создали минимум один раз документы ОказаниеУслуг с комментарием "ДокОсн". Тогда примерно так:
ОкУсл = СоздатьОбъект("Документ.ОказаниеУслуг");
СоздаватьДокумент = 1; //флаг, если нужно создавать новый документ
ОкУсл2 = СоздатьОбъект("Документ.ОказаниеУслуг");
ОкУсл2.ВыбратьДокументы(ДатаНачала, ДатаКонца);
Пока ОкУсл2.ПолучитьДокумент() = 1 Цикл
Если СокрЛП(ОкУсл2.Комментарий) = СокрЛП(ТЗ2.ДокОсн) Тогда //есть оказание услуг, введенное на основании ДокОсн
//если удаляем и создаем новый тогда
ОкУсл2.Удалить();
СоздаватьДокумент = 1;
//или если не создаем
Продолжить;
СоздаватьДокумент = 0;
КонецЕсли;
КонецЦикла;
Если СоздаватьДокумент = 1 Тогда
ОкУсл.Новый();
ОкУсл.Контрагент=ТЗ2.Субконто1;
******
ОкУсл.Всего = ОкУсл.Сумма;
ОкУсл.Комментарий = ТЗ2.ДокОсн;
ОкУсл.Записать();
Примерно так, код не проверял, но идея надеюсь понятна. Можно выборку документов с комментариями сделать заранее, как вариант в виде запроса, и записать все комментарии в еще одну ТЗ и затем искать в ней.
Himik861 пишет:
А почему не будет??? Вроде все правильно
А почему не будет??? Вроде все правильно
ты собираешься сравнить строку со ссылкой на документ. ес-но всегда будет неравно. чтобы ссылку превратить в строку используй функцию сокрлп(<ссылка на документ>)
ты собираешься сравнить строку со ссылкой на документ. ес-но всегда будет неравно. чтобы ссылку превратить в строку используй функцию сокрлп(<ссылка на документ>)
А ещё лучше сделать так: ДокУслуга.Комментарий = ЗначениеВСтрокуВнутр(ДокОснование);
Как вариант, если заливаешь из какой-то внешней OLTP системы, ещё можно создать в кофигурации справочник СозданныеДокУслуги (длина кода = длине номера дока во внешней системе, наименование - 0, + реквизит ДатаДока = ДатаДокУслуга, + реквизит ДокУслуга - ссылка на сам док; один уровень [без групп]).
Тогда можно отслеживать, какой документ из внешней системы загрузился, а какой - нет.
Хотя, проще всё-таки помечать в комментариях, либо в скрытом текстовом реквизите.
ОкУсл = СоздатьОбъект("Документ.ОказаниеУслуг");
ОкУсл.УстановитьФильтр(1, 0); // по желанию
ОкУсл.ВыбратьДокументы(КонецДня, КонецДня);
Пока ОкУсл.ПолучитьДокумент() = 1 Цикл
Если Найти(ОкУсл.Комментарий, ДокОснование.НомерДок) = 1 Тогда
Возврат;
КонецЕсли;
КонецЦикла;
ОкУсл.Новый();
ОкУсл.Комментарий = СокрЛП(ОкУсл.Комментарий) + "/" +СокрЛП(ДокОснование.НомерДок);
и т.д.....
ОкУсл.УстановитьФильтр(1, 0); // по желанию
ОкУсл.ВыбратьДокументы(КонецДня, КонецДня);
Пока ОкУсл.ПолучитьДокумент() = 1 Цикл
Если Найти(ОкУсл.Комментарий, ДокОснование.НомерДок) = 1 Тогда
Возврат;
КонецЕсли;
КонецЦикла;
ОкУсл.Новый();
ОкУсл.Комментарий = СокрЛП(ОкУсл.Комментарий) + "/" +СокрЛП(ДокОснование.НомерДок);
и т.д.....
(23) А если в комментах указан чей то другой номер документа, который случайно совпал с нужным? Бухи свой коммент дописали с номером дока.
Я у себя делал кусок коммента в квадратных скобках, типа [OkUsl:ОУ-0035]. И предупредил, чтобы бухгалтера такой кусок в комменте не трогали и оставляли в самом начале, а свои писали вслед за ним. Тогда вероятность ошибки критически мала и конфу дорабатывать не нужно (Если только не вводят доки копированием и в них не копируется комментарий).
Тогда код немножко другой
Если Лев(ОкУсл.Комментарий,7) = "[OkUsl:" Тогда
Если Сред(ОкУсл.Комментарий,8,7) = ДокОснование.НомерДок Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Поскольку один вид документа может обрабатываться разными обработками для разных целей - у каждой свой префикс. Для данной это "OkUsl"
Я у себя делал кусок коммента в квадратных скобках, типа [OkUsl:ОУ-0035]. И предупредил, чтобы бухгалтера такой кусок в комменте не трогали и оставляли в самом начале, а свои писали вслед за ним. Тогда вероятность ошибки критически мала и конфу дорабатывать не нужно (Если только не вводят доки копированием и в них не копируется комментарий).
Тогда код немножко другой
Если Лев(ОкУсл.Комментарий,7) = "[OkUsl:" Тогда
Если Сред(ОкУсл.Комментарий,8,7) = ДокОснование.НомерДок Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Поскольку один вид документа может обрабатываться разными обработками для разных целей - у каждой свой префикс. Для данной это "OkUsl"
Задача решается тривиально. Сначала определяется уникальный ключ документа - набор реквизитов, который не может повторяться в разных документах. Например: дата + контрагент + сумма + чтохочешьещеможнодобавить.
Потом перед созданием новых документов делается выборка уже существующих документов, выборка по дате (можно добавить другие условия, если они - например, список контрагентов, чтобы оно быстрее шустрило). Выборка складывается в таблицу значений, потом в эту таблицу добавляется колонка "Ключ", которая заполняется строкой вида "" + Док.Дата + "*" + Док.Контрагент + "*" + .... и так все реквизиты, участвующие в ключе.
Потом перед созданием нового документа создается его ключ и ищется в таблице.
Писать ключ в реквизит, который доступен для редактирования пользователем (например, комментарий) - это путь к проблеме. "Я не знаю, я ничего не трогала, а тут не выскакивает" (с) бух - это ж классика жанра.
Потом перед созданием новых документов делается выборка уже существующих документов, выборка по дате (можно добавить другие условия, если они - например, список контрагентов, чтобы оно быстрее шустрило). Выборка складывается в таблицу значений, потом в эту таблицу добавляется колонка "Ключ", которая заполняется строкой вида "" + Док.Дата + "*" + Док.Контрагент + "*" + .... и так все реквизиты, участвующие в ключе.
Потом перед созданием нового документа создается его ключ и ищется в таблице.
Писать ключ в реквизит, который доступен для редактирования пользователем (например, комментарий) - это путь к проблеме. "Я не знаю, я ничего не трогала, а тут не выскакивает" (с) бух - это ж классика жанра.
Не соглашусь. Минус в редактировании пользователем при правильных и умных бухах превращается в плюс отсутствия изменений конфигурации и возможность обновления без привлечения сторонних сил.
То что я написал - как раз и есть ключ. В который я бы не стал писать дату и сумму(Они иногда меняются для подчиненных документов). Достаточно номера дока-основания, ну и например цифр года (для нумераторов периодичностью год, меньшей периодичности мне пока не встречалось в реальных заданиях). И ИМХО нужно ключевое слово, поскольку документы могут образовываться по разным алгоритмам, а "Ключ" типа "дата + контрагент + сумма" не в полной мере позволяет выделить именно нужные по определенной обработке документы.
То что я написал - как раз и есть ключ. В который я бы не стал писать дату и сумму(Они иногда меняются для подчиненных документов). Достаточно номера дока-основания, ну и например цифр года (для нумераторов периодичностью год, меньшей периодичности мне пока не встречалось в реальных заданиях). И ИМХО нужно ключевое слово, поскольку документы могут образовываться по разным алгоритмам, а "Ключ" типа "дата + контрагент + сумма" не в полной мере позволяет выделить именно нужные по определенной обработке документы.
SirStefan пишет:
Не соглашусь. Минус в редактировании пользователем при правильных и умных бухах превращается в плюс отсутствия изменений конфигурации и возможность обновления без привлечения сторонних сил.
Не соглашусь. Минус в редактировании пользователем при правильных и умных бухах превращается в плюс отсутствия изменений конфигурации и возможность обновления без привлечения сторонних сил.
Коллега, правильные и умные бухи - это сферический конь в вакууме.
Ну то есть они есть, но кто их видел-то :). Глав еще бывает такой, а эникейные бухи...
Что касается ключа и изменений в конфигурации, то это все зависит от деталей задачи, которые мы не знаем. А кроме того, такие вещи ведь делаются внешней обработкой и не требуют вообще никаких изменений, в том числе и в работе пользователей.
Если принципиально не трогать конфу. То вариант создать либо ДБФ, либо текстовый файл с разделителями где хранить связку документов и перед обработкой его загружать в ТЗ. Если данные хранить в Комментарии то они могут быть изменены случайно "умными бухами".
Вижу, что лучше ключа решения нет (да и быть имхо не может). Конечно если нельзя трогать конфу, то обработка должна иметь свою базу данных как говорит Denis_Shiln - оставлять служебную информацию в доступных юзерам метах это путь к геморрою.
А у меня был подобный опыт и кажется существует еще один вариант - реквизиты операции или общие реквизиты документа. Можно посмотреть на список общих реквизитов (некоторые из них скрыты), а также если у документа есть операции (он привязан к бух учету, то в операции есть атрибут "Содержание", руками в него как правило глупые бухи не влазят, потому что даже не знают как:).
А у меня был подобный опыт и кажется существует еще один вариант - реквизиты операции или общие реквизиты документа. Можно посмотреть на список общих реквизитов (некоторые из них скрыты), а также если у документа есть операции (он привязан к бух учету, то в операции есть атрибут "Содержание", руками в него как правило глупые бухи не влазят, потому что даже не знают как:).
Есть документ "Заказ". При его закрытии создается документ - "Ордер". При повторном закрытии "Заказе" с новыми реквизитами, надо заменить старый "Ордер" на новый.
Схема реализации в модуле "Заказа" такая:
Процедура ПриЗакрытии()
Если Выбран() и (еще какие-то условия) тогда
//создаем "Ордер"
ИзменилиРеквизиты=0;
ЕстьОрдер=0;
Док = СоздатьОбъект("Документ.Ордер");
Док.ВыбратьДокументы(ДатаДок,ДатаДок);
Попытка
НачатьТранзакцию();
Если Новый=0 Тогда
Пока Док.ПолучитьДокумент()>0 Цикл
Если (Док.Заказ=ТекущийДокумент()) Тогда
Если Док.ПометкаУдаления()<>1 Тогда
ЕстьОрдер=1;
//изменились реквизиты?
Если Док.Реквизит1<>Реквизит2 Тогда ИзменилиРеквизиты=1; КонецЕсли;
//надо внести изменения в имеющийся Ордер?
Если ИзменилиРеквизиты =1 Тогда
Док.Удалить(0);
Док.СнятьПометкуУдаления();
КонецЕсли;
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЕстьОрдер=0 Тогда
Док.Новый();
Док.ДатаДок=ДатаДок;
КонецЕсли
Если (ЕстьОрдер=0) или (ИзменилиРеквизиты=1) Тогда
//пишем новые реквизиты
Док.Реквизит1=...;
Док.СсылкаНаЗаказ=ТекущийДокумент();
Док.Записать();
СсылкаОрдер=Док.ТекущийДокумент();
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Возврат;
КонецПопытки;
КонецЕсли;
КонецПроцедуры //ПриЗакрытии
Ссылку на "Заказ" пишем в "Ордере", а ссылку на "Ордер" в "Заказе". В результате удалить можно только оба документа!
Схема реализации в модуле "Заказа" такая:
Процедура ПриЗакрытии()
Если Выбран() и (еще какие-то условия) тогда
//создаем "Ордер"
ИзменилиРеквизиты=0;
ЕстьОрдер=0;
Док = СоздатьОбъект("Документ.Ордер");
Док.ВыбратьДокументы(ДатаДок,ДатаДок);
Попытка
НачатьТранзакцию();
Если Новый=0 Тогда
Пока Док.ПолучитьДокумент()>0 Цикл
Если (Док.Заказ=ТекущийДокумент()) Тогда
Если Док.ПометкаУдаления()<>1 Тогда
ЕстьОрдер=1;
//изменились реквизиты?
Если Док.Реквизит1<>Реквизит2 Тогда ИзменилиРеквизиты=1; КонецЕсли;
//надо внести изменения в имеющийся Ордер?
Если ИзменилиРеквизиты =1 Тогда
Док.Удалить(0);
Док.СнятьПометкуУдаления();
КонецЕсли;
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЕстьОрдер=0 Тогда
Док.Новый();
Док.ДатаДок=ДатаДок;
КонецЕсли
Если (ЕстьОрдер=0) или (ИзменилиРеквизиты=1) Тогда
//пишем новые реквизиты
Док.Реквизит1=...;
Док.СсылкаНаЗаказ=ТекущийДокумент();
Док.Записать();
СсылкаОрдер=Док.ТекущийДокумент();
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Возврат;
КонецПопытки;
КонецЕсли;
КонецПроцедуры //ПриЗакрытии
Ссылку на "Заказ" пишем в "Ордере", а ссылку на "Ордер" в "Заказе". В результате удалить можно только оба документа!
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот