среда, 3 сентября 2014 г.

Конвертация документов и закрытый период

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

Первое что необходимо сделать создать параметр "Ошибки" в правиле конвертации.
Это простая ТЗ, в которой мы будем собирать ошибки(сообщения) и выводитьпосле обмена именно уникальные сообщения (предварительно свернув таблицу ошибок) .
Инициализируем параметр в обработчике "Перед загрузкой данных"
Параметры.Ошибки=Новый ТаблицаЗначений();
Параметры.Ошибки.Колонки.Добавить("Ошибка");

Сообщение при закрытии кассовой смены: "Не удалось удалить чеки ККМ"

Пользователю необходимо дать право "Администратор ККМ", если оно не установлено.
Также необходимо дать роли "Администратор ККМ" права на удаление чеков и на регистры:
Регистр сведений.Коллизии при обмене
Регистр сведений.Объекты доступа документов
Регистр сведений.Объекты запрещенные для редактирования
Регистр сведений.Отложенные движения документов
Регистр сведений.Соответствие объектов для обмена
Регистр накопления.Продажи (:права на изменение и редактирование)

понедельник, 2 июня 2014 г.

Решение проблемы с разрывом страницы в налоговой накладной в УПП, УТП и Бухгалтерии

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

вторник, 20 мая 2014 г.

воскресенье, 11 мая 2014 г.

среда, 7 мая 2014 г.

среда, 30 апреля 2014 г.

понедельник, 28 апреля 2014 г.

Не работает поиск по дате в конвертации данных

Нашел особенность в переносе документов в конвертации данных: нужно было перенести документ "Реализация товаров и услуг" из УПП в Бухгалтерию, поля поиска у документа были установлены "Номер" и "Дата", поиск по внутреннему идентификатору не использовался. Ничего, вроде, сложного, но есть один нюанс: когда после переноса я поменял дату в базе-источнике (УПП) и попытался перенести ее в базу-источник (Бухгалтерия), то новый документ почему-то не создался (хотя должен был), в нем лишь поменялась дата на новую, которую я установил.
Пришлось анализировать код обработки "Универсальный обмен данными XML", т.к. коллега подсказал, что дело может быть в методе НайтиПоНомеру(), который используется в обработке для поиска документов по их номеру. Здесь есть нюанс в этого метода: поиск будет идти не с проверкой даты на равенство (ДатаВремя1 = ДатаВремя2), а вхождением в интервал(ДатаНач <= ДатаВремя1 <= ДатаКон). Сам интервал определяется как период уникальности номеров документа, в который входит указанная дата. Например, если номера документов уникальны в пределах месяца и задана дата 10 декабря 2001 года, то поиск будет проводиться в интервале с 01 по 31 декабря 2001 года.
В модуле обработки "Универсальный обмен данными XML" нашел такую функцию для поиска документов:

воскресенье, 27 апреля 2014 г.

среда, 23 апреля 2014 г.

Константы

На следующей схеме изображено взаимодействие объектов встроенного языка для работы с константами.

Что означает ОбменДанными.Загрузка = Истина

ОбменДанными.Загрузка – атрибут любого объекта в системе 1С предприятие. Он позволяет обозначить при записи объекта что необходимо отключить любые проверки (в т.ч проверки на уровне платформы 1С). Сделано это было для того, что бы избежать конфликтов при обмене данных.
Если вы разрабатываете свою конфигурацию, в всех проверках правильности данных (например, процедура ПередЗаписью) необходимо первой строкой добавить такую строку:

Если ОбменДанными.Загрузка = Истина Тогда
    Возврат;
КонецЕсли;

Список значений в качестве параметра в СКД

Включить возможность использовать список значений в качестве параметра в СКД можно посредством установки флажка "Доступен список значений" напротив параметра на закладке "Параметры".


Проверка на пустой список значений в запросе

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

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

среда, 16 апреля 2014 г.

Гибкий отбор в таблице значений с использованием построителя запроса

Иногда возникают ситуации, когда нужно сделать отбор в таблице значений используя нечеткое условие, к примеру: больше, меньше, содержит и т.д. Можно, конечно же, использовать перебор в цикле и там уже делать проверку на нечеткие условия, можно использовать метод НайтиСтроки(), вот только отбор, передаваемые туда как параметр, всегда будут иметь вид сравнения - равно.
Что же делать, если нам нужно найти строки в ТЧ и при этом использовать нечеткое условие и не использовать цикл?
Все просто: можно воспользоваться построителем запроса.
Построитель запроса - это объект встроенного языка, с помощью которого мы можем получать необходимые данные, используя отборы.

Пример:
Есть таблица значений ПродукцияТЗ, которая содержит исходные данные. Нужно найти строки, где сумма больше нуля и равна нулю.

вторник, 15 апреля 2014 г.

Конвертация двух табличных частей документа в одну

Для того, чтобы конвертировать две и больше табличные части документа в одну нужно в ПКГС одной из ТЧ в обработчике "ПередОбработкой" написать следующий код:

КоллекцияОбъектов = Источник.ПерваяТабличнаяЧасть.Выгрузить();
Для Каждого
СтрокаТЧ Из Источник.ВтораяТабличнаяЧасть Цикл
   
НовыйСтрока = КоллекцияОбъектов.Добавить();
   
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЧ);
КонецЦикла;

В данном примере сначала в коллекцию объектов выгружаем первую табличную часть, потом обходим вторую ТЧ и дозаполняем коллекцию уже данными из нее.
Правила конвертации второй ТЧ нужно или удалить, или отключить. Они нам уже не понадобятся.

понедельник, 24 марта 2014 г.

У пользователя недостаточно прав на исполнение операции над базой данных

Если при формировании отчета на СКД вы видите сообщение вроде этого:

Ошибка выполнения отчета
по причине:
Ошибка исполнения отчета
по причине:
Ошибка получения данных
по причине:
Ошибка создания набора данных "НаборДанных1"
по причине:
Ошибка при исполнении запроса набора данных
по причине:
Ошибка выполнения запроса
по причине:
У пользователя недостаточно прав на исполнение операции над базой данных.

вторник, 18 марта 2014 г.

Пересчет из валюты в валюту в запросе

Пересчет из валюты в валюту рассмотрим на примере регистра Продажи из УПП.

Пример:
Нужно вывести информацию о ценах проданного товара с пересчетом в заданную валюту на дату документ, т.е. какую валюту пересчета задали в запросе, в такую и пересчитали.

ВЫБРАТЬ РАЗРЕШЕННЫЕ
    КурсыВалют.Период КАК Период,
   
КурсыВалют.Валюта КАК Валюта,
   
КурсыВалют.Курс КАК Курс,
   
КурсыВалют.Кратность
ПОМЕСТИТЬ КурсыВалют
ИЗ
   
РегистрСведений.КурсыВалют КАК КурсыВалют

ИНДЕКСИРОВАТЬ ПО
   
Период,
   
Валюта
;

среда, 12 марта 2014 г.

Типовая функция для пересчета из валюты в валюту

Для пересчета из валюты в валюту в типовых конфигурациях используется функция ПересчитатьИзВалютыВВалюту, расположенная в общем модуле - МодульВалютногоУчета.

Типовая функция для получения курса валют на дату

Для получения курса валюты в таких конфигурациях как: УТ, УТП, УПП и Бухгалтерия существует типовая функция ПолучитьКурсВалюты(Валюта, ДатаКурса), которая располагается в общем модуле МодульВалютногоУчета. Текст функции в данных конфигурациях практически одинаков, отличается, разве что в УПП выводом доп. сообщений и проверкой входных параметров.

четверг, 6 марта 2014 г.

Сохранение параметров и отборов при изменении варианта отчет (толстый клиент)

Как мы знаем, при изменении варианта отчета в СКД, происходит и замена всех его настроек, включая параметры, отборы. Это не очень удобно, т.к. при каждом изменении нужно будет вводить его параметры и отборы вручную. Чтобы выполнить сохранение настроек параметров и отборов при изменении варианта отчета напишем несколько нехитрых строк кода. В качестве примера будет взят ШаблонСКД.epf и в нем доработано сохранение параметров и отборов.

вторник, 21 января 2014 г.

Данные были изменены или удалены другим пользователем (тонкий клиент)

Если при попытке записать элемент справочника или документ появляется ошибка "Данные были изменены или удалены другим пользователем", то это значит, что данные, которые отображаются на форме и данные, которые записаны в базе отличаются.


понедельник, 20 января 2014 г.

Новая методика проведения документа в 1С 8.2

Рассмотрим новую методику проведения на платформе 8.2.  Для этого возьмем демо- конфигурацию "Управляемое приложение" и рассмотрим методику проведения документа "РасходТовара", который делает движения по регистру "ТоварныеЗапасы".

пятница, 17 января 2014 г.

Число прописью

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

// Пример форматной строки для вывода числа прописью на русском
// языке, с выводом целой и дробной части прописью и выводом
// предмета исчисления.
ФормСтрока = "Л = ru_RU; ДП = Истина";
ПарПредмета="доллар,доллара,долларов,м,цент,цента,центов,м,2";
ПрописьЧисла = ЧислоПрописью(2341.56, ФормСтрока, ПарПредмета);

// Результат вычисления:
// "Две тысячи триста сорок один доллар пятьдесят шесть центов"


Количество прописью

Для формирования количества прописью можно использовать стандартную функцию, расположенную в общем модуле ФормированиеПечатныхФорм:

// Стандартная для данной конфигурации функция форматирования прописи количества
//
// Параметры:
//  Количество - число, которое мы хотим форматировать
//
// Возвращаемое значение:
//  Отформатированная должным образом строковое представление количества.
//
Функция КоличествоПрописью(Количество, КодЯзыка = "ru") Экспорт

   
ЦелаяЧасть   = Цел(Количество);
   
ДробнаяЧасть = Окр(Количество - ЦелаяЧасть, 3);

    Если
ДробнаяЧасть = Окр(ДробнаяЧасть,0) Тогда
       
ПараметрыПрописи = ", , , , , , , , 0";
    ИначеЕсли
ДробнаяЧасть = Окр(ДробнаяЧасть, 1) Тогда
       
ПараметрыПрописи = НСтр("ru='целая, целых, целых, ж, десятая, десятых, десятых, м, 1';uk='ціла ,цілих ,цілих , ж, десята, десятих, десятих, м, 1'",КодЯзыка);
    ИначеЕсли
ДробнаяЧасть = Окр(ДробнаяЧасть, 2) Тогда
       
ПараметрыПрописи = НСтр("ru='целая, целых, целых, ж, сотая, сотых, сотых, м, 2';uk='ціла ,цілих ,цілих , ж, сота, сотих, сотих, м, 2'",КодЯзыка);
    Иначе
       
ПараметрыПрописи = НСтр("ru='целая, целых, целых, ж, тысячная, тысячных, тысячных, м, 3';uk='ціла ,цілих ,цілих , ж, тисячна, тисячних, тисячних, м, 3'",КодЯзыка);
    КонецЕсли;

    Возврат
ЧислоПрописью(Количество,"Л="+Локализация.ОпределитьКодЯзыкаДляФормат(КодЯзыка), ПараметрыПрописи);

КонецФункции
// КоличествоПрописью()

Пример вызова функции:
ОбластьМакета.Параметры.ВсегоПрописью = ФормированиеПечатныхФорм.КоличествоПрописью(Всего, "uk");

Убрать лидирующие нули из номера документа

Убрать лидирующие нули из номера документа может нам понадобиться в том случае, если мы, к примеру, формируем печатную форму и номер нужно привести к нормальному виду, не показывая лидирующие нули и префикс документа. Для этого можно воспользоваться готовой процедурой, которая преобразовывает номер к нужному нам виду. Содержится она в общем модуле ОбщегоНазначения:

среда, 15 января 2014 г.

Переопределение процедуры ввода по строке в управляемом приложении

Для того, чтобы определить свой набор данных, которые формируются при вводе по строке нужно использовать событие АвтоПодбор() элемента формы.
Справка из синтаксис-помощника:
АвтоПодбор (AutoComplete)
Синтаксис:
АвтоПодбор(<Текст>, <ДанныеВыбора>, <Ожидание>, <СтандартнаяОбработка>)
Параметры:
<Текст>
Тип: Строка.
Строка текста, введенная в поле ввода.
<ДанныеВыбора>
Тип: СписокЗначений.
Содержит список значений, который будет использован при стандартной обработке события.

вторник, 14 января 2014 г.

Начало сеанса с информационной базой запрещено. Резервное копирование

При запуске информационной базы выскакивает окно типа "Ожидание запуска" в нем пишет: Начало сеанса с ИБ запрещено. Резервное копирование.
Для администратора: для того что бы разблокировать информационную базу, воспользуйтесь консолью кластера серверов или запустите 1С с параметрами: ENTERPRISE/F"C\1cv82\1C\Trade1"/СРазрешитьРаботуПользователей/UC<код разрешения>


 Чтобы убрать данную ошибку достаточно удалить 1Cv8.cdn в папке с базой и все.

пятница, 10 января 2014 г.

Возврат товара от покупателя, если реализация была выполнена на основании заказа

Рассмотрим такой пример:
Покупатель купил 10 единиц товара, через некоторое время он вернул 2 единицы. Вначале был оформлен документ "Заказ покупателя", потом на его основании "Реализация товаров и услуг", для возврата - "Возврат товаров от покупателя" (создан на основании документа реализации). При анализе пользователь обнаружил, что в отчете "Ведомость по заказам покупателей" в колонке "Конечный остаток" для данного товара стоит 2, а также в отчете "Анализ заказов" для данного товара в колонках "Осталось отгрузить",  "Осталось обеспечить" стоит цифра 2, а в "Оплата", "Осталось оплатить" - сумма 100 (сумма за 2 единицы товара).
Получается, что организация должна покупателю товар, а он ей деньги...

В данном случае нужно учитывать, что при возврате по реализации сразу же происходит и возврат по заказу и как следствие, система решает, что, если товар не был реализован, значит и заказ не выполнен. Поэтому после возврата нужно делать документ "Закрытие заказов покупателей", указав в комментарии причину "возврат покупателя" и если нужно оформить новый заказ покупателя.

четверг, 9 января 2014 г.

GUID или уникальный идентификатор объекта

GUID (Globally Unique Identifier) - статический уникальный 128-битный идентификатор. Его главная особенность - уникальность, которая позволяет создавать расширяемые сервисы и приложения без опасения конфликтов, вызванных совпадением идентификаторов. Хотя уникальность каждого отдельного GUID не гарантируется, общее количество уникальных ключей настолько велико (2128 или 3,4028×1038), что вероятность того, что в мире будут независимо сгенерированы два совпадающих ключа, крайне мала.
В тексте GUID записывается в виде строки из тридцати двух шестнадцатеричных цифр, разбитой на группы дефисами:
6F9619FF-8B86-D011-B42D-00CF4FC964FF

Получить GUID элемента можно так:
НоменклатураСсылка = Справочники.Номенклатура.НайтиПоНаименованию("Чайник");
Если НЕ
НоменклатураСсылка.Пустая() Тогда
  
Сообщить("GUID = " + НоменклатураСсылка.УникальныйИдентификатор());
КонецЕсли;

Получить элемент по GUID:
ГУИДВидНоменклатуры = Новый УникальныйИдентфикатор(TypeGUID);
ВидНоменклатуры = Справочники.ВидыНоменклатуры.ПолучитьСсылку(ГУИДВидНоменклатуры);

понедельник, 6 января 2014 г.

Округление всегда в большую сторону в запросе

Запрос для пересчета количества заказываемого товара в большую сторону, с учетом количества товара содержащимся в одной упаковке.

ВЫБРАТЬ
   
ЗаказПоставщикуТовары.Номенклатура,
   
ЗаказПоставщикуТовары.Количество,
   
ЗаказПоставщикуТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент КАК ЕдиницаХраненияОстатковКоэффициент,
   
ЗаказПоставщикуТовары.Номенклатура.ЕдиницаДляОтчетов.Коэффициент КАК ЕдиницаДляОтчетовКоэффициент,
   
ЗаказПоставщикуТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент / ЗаказПоставщикуТовары.Номенклатура.ЕдиницаДляОтчетов.Коэффициент КАК ДоляВУпаковке,
   
ЗаказПоставщикуТовары.Количество * (ЗаказПоставщикуТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент / ЗаказПоставщикуТовары.Номенклатура.ЕдиницаДляОтчетов.Коэффициент) КАК КоличествоУпаковок
ПОМЕСТИТЬ втЗаказПоставщику
ИЗ
   
Документ.ЗаказПоставщику.Товары КАК ЗаказПоставщикуТовары
ГДЕ
   
ЗаказПоставщикуТовары.Ссылка = &Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   
втЗаказПоставщику.Номенклатура,
   
втЗаказПоставщику.Количество,
   
втЗаказПоставщику.ЕдиницаХраненияОстатковКоэффициент,
   
втЗаказПоставщику.ЕдиницаДляОтчетовКоэффициент,
   
втЗаказПоставщику.ДоляВУпаковке,
   
втЗаказПоставщику.КоличествоУпаковок,
   
ВЫРАЗИТЬ(втЗаказПоставщику.КоличествоУпаковок - 0.5 КАК ЧИСЛО(10, 0)) КАК ЧислоЦелыхЧастей,
   
втЗаказПоставщику.Количество - втЗаказПоставщику.ЕдиницаДляОтчетовКоэффициент * (ВЫРАЗИТЬ(втЗаказПоставщику.КоличествоУпаковок - 0.5 КАК ЧИСЛО(10, 0))) КАК ОстатокЦелого
ПОМЕСТИТЬ втЗаказПоставщикуУпаковка
ИЗ
   
втЗаказПоставщику КАК втЗаказПоставщику
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   
втЗаказПоставщикуУпаковка.Номенклатура,
   
втЗаказПоставщикуУпаковка.Количество,
   
втЗаказПоставщикуУпаковка.ЕдиницаХраненияОстатковКоэффициент,
   
втЗаказПоставщикуУпаковка.ЕдиницаДляОтчетовКоэффициент,
   
втЗаказПоставщикуУпаковка.ДоляВУпаковке,
   
втЗаказПоставщикуУпаковка.КоличествоУпаковок,
   
втЗаказПоставщикуУпаковка.ЧислоЦелыхЧастей,
   
втЗаказПоставщикуУпаковка.ОстатокЦелого,
   
ВЫБОР
        КОГДА
втЗаказПоставщикуУпаковка.ОстатокЦелого = 0
           
ТОГДА втЗаказПоставщикуУпаковка.ЧислоЦелыхЧастей
        ИНАЧЕ втЗаказПоставщикуУпаковка.ЧислоЦелыхЧастей + 1
   
КОНЕЦ * втЗаказПоставщикуУпаковка.ЕдиницаДляОтчетовКоэффициент КАК КоличествоСУчетомУпаковки
ИЗ
   
втЗаказПоставщикуУпаковка КАК втЗаказПоставщикуУпаковка


пятница, 3 января 2014 г.

Назначить конкретный тип элементу формы, который связан с реквизитом формы, имеющим составной тип

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

Объект.ОтветЛицо ПредопределенноеЗначение("Справочник.ФизическиеЛица.ПустаяСсылка");

Если запретить выбор типа в поле ввода (свойство ВыбиратьТип), то реквизиту ОтветЛицо будет назначен тип ссылки на справочник ФизическиеЛица, и для выбора будут предлагаться значения только этого справочника.
Также можно использовать свойство поля ввода ОграничениеТипа, задающее возможные типы данных, которые могут быть введены в поле ввода, и приводить значение соответствующего реквизита к нужному типу:

Массив = Новый Массив();
Массив.Добавить(Тип("СправочникСсылка.ФизическиеЛица"));
НашеОписание = Новый ОписаниеТипов(Массив);
Элементы.ОтветЛицо.ОграничениеТипа = НашеОписание;
Объект.ОтветЛицо = НашеОписание.ПривестиЗначение(Объект.ОтветЛицо);

Программно очистить реквизит в форме

Для того чтобы очистить реквизит в форме, следует присвоить этому реквизиту значение по умолчанию.
Например, для реквизита Контрагент имеющего тип СправочникСсылка.Контрагенты фрагмент кода будет выглядеть следующим образом:

Объект.Контрагент ПредопределенноеЗначение("Справочник.Контрагенты.ПустаяСсылка");

Получить предопределенное значение на клиенте

Т.к. обращение к менеджерам объектов (например, Справочники.<Имя справочника>) на клиенте недоступно, то для получения ссылки на предопределенное значение на клиенте следует использовать метод глобального контекста ПредопределенноеЗначение(). Например, требуется открыть форму предопределенного элемента справочника. Это можно сделать с помощью следующего кода:

&НаКлиенте
Процедура СоздатьСобытие(Команда)

   
ВидСобытия = ПредопределенноеЗначение("Справочник.ВидыСобытий.Встреча");
   
ОткрытьЗначение(ВидСобытия);

КонецПроцедуры