В этой статье я расскажу, как загружать данные в 1с 8 из простейших текстовых файлов с разделителями. Обычно они имеют расширение csv (Comma-Separated Values). Т. е. название подразумевает, что в каждой строке такого текстового файла значения разделены запятой. Но на самом деле, запятую, в качестве разделителя, использовать не надёжно. Поэтому применяют другие разделители, которые в обычном тексте встречаются редко. Это могут быть символы «^», «~»,«|» и другие. Итак, наша задача состоит в том, чтобы загрузить имеющуюся в csv файле информацию в базу данных 1с. Например, в файле будут содержаться товары интернет - магазина. В качестве образца, я взял выгрузку из магазина на скрипте virtuemart. Посмотрим, как выглядит файл.
Привожу две первых строки из него:
Посмотрим на файл.
Первая строка служебная. В ней описан формат нашего файла. Т. е. в какой ячейке, что находится. Однако, имейте в виду, что такой строки может и не быть.
Ячейки образуются при помощи разделителя «^», а данные в ячейках обрамляются символом «~».
В любой конфигурации 1с есть иерархический справочник товаров. В него и будем загружать информацию.
Создадим внешнюю обработку. Добавим строковый реквизит «путьКФайлуЗагрузки» для хранения имени файла. Добавим на форму поле ввода, связанное с данным реквизитом. Включим в свойствах поля ввода кнопку выбора и создадим обработчик события «НачалоВыбора» и напишем в нём такой код:
Т. о. мы организовали диалог для выбора файла в нашей обработке.
Хорошо. Теперь, для удобства и наглядности я предлагаю создать временную табличку, в которую мы загрузим текстовый файл, а уже после её заполнения - будем осуществлять загрузку в базу 1с. Для этого, на форму добавим табличное поле «табЗагрузки», с типом значения «ТаблицаЗначений» и командной панелью. В панели поместим кнопку «Заполнить» и создадим обработчик её нажатия «КоманднаяПанель1Заполнить». Также для элемента универсальности, добавим в обработку два строковых реквизита «символОграничения» и «разделительПолей». В них мы будем хранить «^», и «~». Можно в теле модуля формы осуществить их начальную инициализацию:
разделительПолей = "^";
символОграничения = "~";
Это позволит пользователю задать свои значения и при желании сохранить настройку, которая впоследствии не затрется нашей инициализацией.
Функцию разложения строки с разделителями в массив можно разместить как в одном из общих модулей, так и непосредственно в обработке.
Отлично. В итоге, после заполнения, получим примерно такую картинку:
Теперь приступим непосредственно к загрузке товаров. Рядом с кнопкой «заполнить» добавим кнопку «загрузить» и добавим обработчик её нажатия «КоманднаяПанель1Загрузить», а также добавим реквизит «ПапкаЗагрузкиВыгрузкиТоваров» с типом вашего справочника товаров для опциональной их загрузки в определенную папку. Текст обработчика будет такой:
В приведенном коде две новые функции «вернутьТовар» и «ЗаписатьЭлементСпр». Вот их текст:
И осталась последняя новая функция для обработки родителя товара вернутьРодителяТовара. Текст её смотрите ниже. Комментарии по тексту.
Часто при ведении учета в различных конфигурациях 1с возникает необходимость выполнения обмена данных. Для решения этой задачи принято использовать Универсальный обмен данными XML или другие внешние обработки, общим у которых является использование текстовых файлов посредников.
Я предлагаю использовать Web-сервисы 1с. В чем необходимость обмена: Обмен данными между базами требуется для исключения дублирующих вводов одних и тех же данных в различных учетных системах. В чем необходимость обмена в режиме online: Обмен в онлайн режиме требуется когда функции учета комплекса учетных систем выполняются в разных учетных системах.
1. Например компания использует: CRM систему учета, для ведения учета взаимоотношений с клиентами; БП 2.0 для ведения взаиморасчетов с клиентами в разрезе счетов; Счета выставляемые клиентам создаются в торговой базе, а оформление заказов поставщикам исходя из потребности клиентов в базе ориентированной на работу с пайсами поставщиков. При таком разделенном построении учета, для выставления счета в одной из баз к примеру требуется завести карточку клиента в другой базе с тем чтобы данные о контрагенте так же были доступны в базе со счетами.
2. Помимо синхронизации первичных данных, может возникнуть необходимость построения сводного отчета по данным из нескольких баз, что тоже потребует обращения к внешним данным в online режиме.
Вариант автоматизации данного процесса с использованием файлов обмена, потребует подключения обработчика ожиданий, что сможет обеспечить обмен данными только с установленной задержкой времени обмена, кроме того любая обработка ожидания будет не эффективно использовать машинное время.
Обращение к Web сервисам, возможно при возникновении любых событий (ПриЗаписи, ПриПроведении, при нажатии кнопки и т.д.). при этом не возникнет ни какой задержки реакции информационной базы к которой происходит обращение, (в отличие от запуска еще одного приложения 1с в качестве com объекта).
Итак рассмотрим вариант реализации синхронизации элементов справочников, начнем с наиболее простого со справочника "Товары" в базах "Продажи" и "Закупки". Синхронизация для начала будет односторонней, предположим что перечень товаров заводится в базе "Продажи", а в "Закупки" он передается.
Что нам потребуется для того чтобы задача возникла и могла быть решена.
1. Сервер 1с, с установленной web компонентой;
2. веб-сервер (например IIS 6.0);
3. Две или более конфигурации учетных систем.
Что нам потребуется для решения задачи.
1. Создадим в базе "Закупки" Web-сервис "Синхронизация", и добавим ему Операцию "СинхронизироватьТовар", со строковыми параметрами.
1. "GuidТовара" - сюда будем передавать уникальный идентификатор товара присвоенный в базе Продаж.
2. "GuidРодителя" - уникальный идентификатор родителя данного товара.
3. "стрСтруктураРеквизитов" - Структура реквизитов товара в виде примитивных типов (число,строка,дата,булево) преобразованная в строку.
4. "этоГруппа" - реквизит котрый позволит нам не раскрывая всей структуры реквизитов товара узнатья явлется ли товар группой и соответственно его обработать.
5. "стрТаблицаЕденицИзмерения" - Таблица содержащая описание доступных единиц измерения для товара
Далее потребуется опубликовать данный сервис на веб сервере. для этого нужно будет создать текстовый файл "wssinhron.1cws", в каталоге сайта опубликованном на веб сервере. Библиотека wsisapi.dll, должна быть подключена. Проще всего корректную настройку работы веб сервера с 1с можно провести опубликовав веб приложение через конфигуратор Администрирование->"Публикация на веб сервере". Единственным минусом является, то что в версии 8.2 файлы веб сервисов *.1cws, сами не создаются. Возможно просто мне не хватает знаний по этому вопросу но для публикации веб сервисов я пользуюсь блокнотом.
Также следует учесть что на серверах 64x следует использовать wsisapi.dll из поставки 1с 64x, даже если сам сервер 1с у вас 86x.
Итак создаем файл "wssinhron.1cws" с текстом.
{Название вашего сервера 1с}";Ref="{Назваение базы. у нас это "Market"}";"/>
Далее перейдем в модуль обработки нашего Сервиса, для наглядности я приведу пример кода своей разработки
Теперь, как вызвать веб сервис не зациклив при этом систему.
в нашем справонике "Товары" в базах "Продажи" и "Закупки" нам потребуются служебные реквизиты. 1. "GUIDтовара" - строковый реквизит (50)
2. "ВремяСинхронизации" - Реквизит с типом Дата и Время
3. "Синхронизирован" - тип булево.
В модуль объекта Справочника добавим предопределенные обработчики событий "ПередЗаписью()", "ПриЗаписи()" функцию "Синхронизация()" и общую переменную "передавать", и под текстом модуля присвоим этой переменной значение Истина. Перем передавать Экспорт;
Процедура ПередЗаписью(Отказ)
Процедура ПриЗаписи(Отказ)
Функция Синхронизация()
передавать = истина;
Таким образом получится что при любой инициализации модуля наша переменная всегда имеет значение истина.
Рассмотрим наши процедуры:
Таким образом остается добавить в событие формы элемента "ПриЗаписи()"
И мы сможем записывать наш элемент сколько угодно раз не вызывая зацикливания.
Для варианта двусторонней синхронизации, (когда элемент справочника может редактироваться в обоих базах) нам потребуется скопировать наш веб сервис из базы закупок в базу продаж переименовав имя файла публикации и URI пространство имен и внести соответствующие изменения в вызов веб сервиса из базы продаж в базу закупок и опубликовать его. Важно: При успешном срабатывание вызванного сервиса из базы "Продажи", в качестве результата работы должен быть возвращен уникальный идентификатор элемента справочника из базы "Продажи". Данный результат необходимо будет присвоить соответсвующиму реквизиту справочника из базы закупок.
Аналогично приведенному примеру можно синхронизировать данные любого справочника или документа.
Построение сводных отчетов
Для получения сводного отчета нам также потребуется вызов веб сервиса из какой - либо базы. Данный веб сервис должен будет возвращать преобразованною в строку, таблицу с данными которые мы хотим использовать в нашем отчете (Например таблицу содержащую "Код товара" и "Актуальную цену поставщика на данный товар"). Далее можно преобразовать эту строку в таблицу и использовать в качестве вложенной временной таблицы любом запросе к базе "Продажи" с соединением по Коду. Исключением является использование данной таблицы в Построителе отчетов, для случая построителя нам понадобится создание, дополнительного справочника с предопределенным элементом и табличной частью, с реквизитами соответствующими полям таблицы.
Автор: allert73
Эту статью я посвящаю двум процедурам ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр. Они являются полным «антиподом действий» друг другу, а разработчики 1с предприятия отнесли их в раздел «Процедуры и функции сохранения значений».
Почему именно так они названы, для чего они полезны ну и конечно же почему эти функции ассоциируются с сохранением значений попробую разъяснить.
С этими функциями я познакомился еще, когда начинал свою деятельность 1с программиста в программных продуктах семейства 1с предприятия версии 7.7, обратил я на них внимание впервые, когда мне необходимо было сохранять сложные типы данных (например, заполненную таблицу значений, структуру и т.д.).
А т.к. средствами 1с можно представить различные типы значений в виде строки (с использованием процедуры ЗначениеВСтрокуВнутр), задачка моя упростилась. И вот собственно описание этих двух простых, но очень полезных функций.
ЗначениеВСтрокуВнутр
Функция ЗначениеВСтрокуВнутр преобразует или другими словами приводит в строковое представление данные, т.е. данные преобразуются в специальный строковый формат, который можно использовать только внутри одной информационной базы, это очень важно!
Например, у нас есть массив:
А преобразование данного массива в строковое представление будет иметь вид: {«#»,51e7a0d2-530b-11d4-b98a-008048da3034,{3, {«S»,»Тара»},{«S»,»Контейнер»},{«S»,»Паллет»}}}
ЗначениеИзСтрокиВнутр
Функция ЗначениеИзСтрокиВнутр производит обратное преобразование из строкового представления данных во внутреннее представление системы 1с предприятия. Т.е. если выполнить код вида:
Мы в переменную «МассивЗначений» передаем уже не строку, а определенный тип данных «Массив» причем массив уже заполненный ранее. Источник
При копировании из «1С:Предприятие» через буфер обмена текст вставляется в другой кодировке?
Избавляемся от этой проблемы с помощью нехитрых манипуляций.
Попробуем скопировать из конфигуратора любую часть текста, например строку:
Бывает так, что при вставке из буфера обмена в текстовый документ (например, блокнот или Word) получаем текст в виде иероглифов!
Конечно, при копировании можно контролировать текущую раскладку, чтобы был включен русский язык, тогда проблем при копировании не возникнет. Но кому хочется следить за этим и делать что-то второй раз, копируя данные повторно?
С помощью программы regedit (Пуск\Выполнить\regedit) нужно открыть реестр Windows и найти путь: НKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Codepage
В строке с именем 1252 установить строковый параметр c_1251.nls.
После этого перезагружаем компьютер и забываем о проблеме некорректного отображения текста.
В языке запросов 1С:Предприятия функция ПОДСТРОКА() в формате ПОДСТРОКА(<Исходная строка>, <Начало>, <Длина>) может применяться к данным строкового типа и позволяет выделить фрагмент <Исходной строки>, начинающийся с символа номер <Начало> (символы в строке нумеруются с 1) и длиной <Длина> символов. Результат вычисления функции ПОДСТРОКА() имеет строковый тип переменной длины, причем длина будет считаться неограниченной, если <Исходная строка> имеет неограниченную длину и параметр <Длина> не является константой или превышает 1024.
Вычисление функции ПОДСТРОКА() на SQL сервере:
В клиент-серверном варианте работы функция ПОДСТРОКА() реализуется при помощи функции SUBSTRING() соответствующего оператора SQL, передаваемого серверу баз данных SQL Server, который вычисляет тип результата функции SUBSTRING() по сложным правилам в зависимости от типа и значений ее параметров, а так же в зависимости от контекста, в котором она используется.
В большинстве случаев эти правила не оказывают влияния на выполнение запроса 1С:Предприятия, однако есть случаи, когда для исполнения запроса существенна максимальная длина строки результата, вычисленная SQL Server. Важно иметь в виду, что в некоторых контекстах использования функции ПОДСТРОКА() максимальная длина ее результата может оказаться равной максимальной длине строки ограниченной длины, которая в SQL Server равна 4000 символам. Это может привести к неожиданному аварийному завершению выполнения запроса.
Например, запрос:
завершается аварийно с сообщением Ошибка СУБД: Microsoft OLE DB Provider for SQL Server: Warning: The query processor could not produce a query plan from the optimizer because the total length of all the columns in the GROUP BY or ORDER BY clause exceeds 8000 bytes.
HRESULT=80040E14, SQLSTATE=42000, native=8618
Это происходит потому, что вычисленная Microsoft SQL Server максимальная длина строки, которая является результатом выражения:
равна 4000 символов. Поэтому длина записи, состоящей из двух таких полей превышает 8000 байт, разрешенные для выполнения операции сортировки.
В связи с описанной особенностью исполнения функции SUBSTRING() на SQL Server использование функции ПОДСТРОКА() с целью приведения строк неограниченной длины к строкам ограниченной длины не рекомендуется. Вместо нее лучше использовать операцию приведения типа ВЫРАЗИТЬ(). В частности, приведенный пример можно переписать в виде: