Имя: Пароль:
1C
1С v8
Можно ли из другой системы перебрать соответствие и структуру
0 Andy_Yuferov
 
30.01.18
14:26
Имеется подключение из C# через OLE к базе 8.3, 8.2 как на тонком, так и на толстом клиенте. Подключение получает внешнюю обработку, которая выполняет вычисление и возвращает результат. Результат, естественно, в формате 1С и надо перегнать его. Результат имеет сложную структуру и содержит разные типы 1С: структуры, списки значений, массивы, соответствия, ссылки и прочий треш. В общем основная проблема в том, что нет методов, которые бы дали коллекцию ключей структур и соответствий а по индексу обращение невозможно. Может кто-нибудь знает вариант, как можно перебрать через соединение с 1С соответствие и структуру, или получить коллекцию ключей? Вариант с добавлением в конфигурацию или обработку методов, которые вернут то, что надо сразу забраковали, так как менять тот функционал запрещено. Можно использовать Выполнить и Вычислить. Но как туда верно что-то прописать - ума не приложу. Есть идея насчет перегона значения в строку и брать ключи оттуда, но у соответствия ключом может быть что угодно и этого хотелось бы избежать.
1 Dotoshin
 
30.01.18
14:34
(0) Такой вариант не подойдет?

Внешнее соединение (External connection)
Методы:

NewObject (NewObject)
String (String)

Описание:

В общем и целом работа с 1С:Предприятием 8 через внешнее соединение подобна работе с 1С:Предприятием в режиме Automation сервера. Основные отличия заключаются в следующем:
В случае Automation сервера запускается полноценное приложение 1С:Предприятия 8, а в случае внешнего соединения запускается относительно небольшой внутрипроцессный COM-сервер.
При работе через внешнее соединение не доступны функциональные возможности, так или иначе связанные с организацией пользовательского интерфейса 1С:Предприятия 8;
При работе внешнего соединения не используется модуль управляемого приложения (модуль обычного приложения) конфигурации 1С:Предприятия 8. Его роль при работе с внешним соединением играет модуль внешнего соединения.
При использовании внешнего соединения имеются следующие преимущества по сравнению с использованием Automation сервера:
Более быстрая установка соединения, так как не требуется создания отдельного процесса операционной системы, а все действия производятся в рамках вызывающего процесса;
Более быстрое обращение к свойствам и методам объектов 1C:Предприятия, так как для организации обращения не требуется организации межпроцессной коммуникации;
Меньший расход ресурсов операционной системы.
Для организации доступа к данным 1С:Предприятия 8 через внешнее соединение, выполняется следующая последовательность действий:
создается менеджер COM-соединений, с помощью которого производится установка соединения;
производится обращение к методу Connect менеджера COM-соединений. Метод Connect возвращает внешнее соединение с информационной базой 1С:Предприятия 8;
через внешнее соединение производится обращение к допустимым методам, свойствам и объектам информационной базы, с которой установлено соединение.
Важно! В связи с отсутствием пользовательского интерфейса не все объекты, а также свойства и методы можно использовать во внешнем соединении.
Внешнее соединение предоставляет полный доступ к своему глобальному контексту. Поэтому внешнее соединение в качестве своих методов может иметь: системные константы, значения заданных в конфигураторе объектов, доступ к которым осуществляется с помощью менеджеров (например, константы, перечисления, справочники, документы, журналы документов, отчеты, обработки, планы видов характеристик, планы счетов, планы видов расчета, регистры), а также переменные, объявленные в модуле внешнего соединения с ключевым словом Экспорт.

Доступность:

Интеграция.
Пример:

// Создание объекта-коннектора
cntr = Новый COMObject("V82.COMConnector");
// создается объект COM-соединение
connection = cntr.Connect("File=""c:\InfoBases\Trade"";Usr=""Director"";");
СпрКонтрагенты = connection.Справочники.Контрагенты;
Выборка = СпрКонтрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Наименование);
КонецЦикла;

// Пример на языке MS Visual Basic
Sub Excel_to_trade()
    Dim cntr As Object
    Dim trade As Object
    Dim Товар As Object
    Set cntr = CreateObject("V82.COMConnector")
    Set trade = cntr.Connect("File=""c:\InfoBases\Trade""; Usr=""Director"";")
    Set Товар = trade.Справочники.Товары
    Группа = Товар.СоздатьГруппу()
    Группа.Наименование = "***** Экспорт из Excel ******"
    Группа.Записать()
    N = 100   'Количество строк в документе
    For Count = 1 To N
        Элемент = Товар.СоздатьЭлемент()
        Элемент.Наименование = Application.Cells(Count, 2).Value
        Элемент.Розн_Цена = Application.Cells(Count, 3).Value
        Элемент.Мел_Опт_Цена = Application.Cells(Count, 4).Value
        Элемент.Опт_Цена = Application.Cells(Count, 5).Value
        Элемент.Родитель = Группа.Ссылка
        Элемент.Записать()
    Next Count
End Sub


См. также:

Соединение с рабочим процессом, метод Connect
Менеджер COM-соединений, метод Connect
Глобальный контекст, метод ПолучитьСообщенияПользователю
2 бомболюк
 
30.01.18
14:34
IEnumVariant
3 Andy_Yuferov
 
30.01.18
14:39
(1) Штука в том, что у структур и соответствий нет Следующий(), её нельзя выбрать, нельзя выгрузить. Они перебираются встроенным методом "для каждого", а как вызвать эту конструкцию через соединение я не нашёл. При этом ключей нет, а по индексу получить ключ-значение никак. Хотя метод получения размера есть.
4 Волшебник
 
модератор
30.01.18
14:42
(3) Есть возможность получения по индексу
Структура.Свойство
Соответствие.Получить
5 Волшебник
 
модератор
30.01.18
14:42
(4)* по ключу
6 Serg_1960
 
30.01.18
14:44
(0) "Подключение получает внешнюю обработку, которая выполняет вычисление и возвращает результат. Результат, естественно, в формате 1С... Вариант с добавлением в конфигурацию или обработку методов, которые вернут то, что надо сразу забраковали, так как менять тот функционал запрещено." - хмм...

В принципе, результат может быть в любом другом формате представлен несмотря на озвученные ограничения. Пишите свою внешнюю обработку, которая получает результат работы исходной обработки и конвертирует данные в нужный Вам формат.
7 Serg_1960
 
30.01.18
14:53
Может быть я сложно сказал? "Подключение получает внешнюю обработку..." - а далее следует ещё одно подключение, но с вызовом уже вашей обработки - конвектором результата предыдущей обработки.
8 Andy_Yuferov
 
30.01.18
14:56
(2) Интерфейс даёт возможность написать свой перебор. Я не знаю, как вызвать перебор 1С.
9 Andy_Yuferov
 
30.01.18
14:57
(5) Да, а ключи я не знаю. Результат может быть с совсем разнообразными полями.
10 Andy_Yuferov
 
30.01.18
14:58
(7) Да нет, всё в принципе понятно. Костыль, конечно. Но на безрыбье и рак рыба. Спасибо за вариант.
11 lodger
 
30.01.18
14:59
(9) зачем вам костыль к костылю для костыля? напишите потребную отбработку в базе получателе с подключением к источнику.
12 Andy_Yuferov
 
30.01.18
15:02
(11) Своя специфика. Данные должны попасть не в базу 1С.
13 бомболюк
 
30.01.18
15:04
(8) методы интерфейса позволят организовать перебор на стороне C#. Запрашиваешь интерфейс у объекта, используешь методы - только и делов.
14 Serg_1960
 
30.01.18
15:11
Кстати, Выполнить() позволяет исполнить произвольные алгоритмы 1С практически без ограничений для целей автора. я не понимаю в чём проблема? Автор не знает языка 1С?
15 Dotoshin
 
30.01.18
15:15
(3) В C# нет оператора for each?
16 Serg_1960
 
30.01.18
15:25
*(14) У меня, например, через вызов этой функции, пользователи заполняют однотипные спецификации в конфигурации УПП. Изначально обработчики для тиражирования спецификаций пишу я, а потом передаю пользователям для эксплуатации. Они хранятся в базе в виде текста, доступного пользователям для редактирования. Пользователи, по мере возникновения потребности, могут оперативно изменять различные коэффициенты, формулы расчета и сами исходных комплектующие.
17 Andy_Yuferov
 
30.01.18
15:30
(14) Я знаю, что позволяет. Но я написал, что не знаю, как через Выполнить вызвать перебор структуры и вернуть, допустим, массив ключей. Чтобы "Выполнить" отработало нормально нужно сперва объявить переменную и в тексте "Выполнить" указать что с ней сделать, а затем вернуть её. Я не могу так сделать через соединение - нужна функция в 1С.
18 Andy_Yuferov
 
30.01.18
15:30
(15) Есть, но для его использования C# должен знать, что делать с объектом для его перебора.
19 arsik
 
гуру
30.01.18
15:33
(18) Создай в 1с функцию. СоответствиевМассив, структуруВМассив.
20 arsik
 
гуру
30.01.18
15:36
Ну и у структуры и соответствия есть метод Количество().
Потом делаешь перебор по индексам.
21 Serg_1960
 
30.01.18
15:38
(17) Зато у Вас есть возможность изменять непосредственно сам исполняемый алгоритм перед вызовом Выполнить(). Принцип тот же самый как, например, в типовых конфигурациях конструируется текст запроса на лету по мере необходимости.
22 Dotoshin
 
30.01.18
15:39
(18) Как понять С# должен знать, что делать с объектом?
Для перебора ничо знать не надо. Ты тупо перебираешь элементы коллекции А вот чо делать с этими элементами, наверно зависит от этих элементов...
23 Andy_Yuferov
 
30.01.18
15:43
(20) Ну я же сказал, что у структур и соответствий НЕЛЬЗЯ получить элемент по индексу.
(19) И что нельзя менять код в 1С тоже. Только если сделать отдельную обработку, как предложили выше.
24 Вафель
 
30.01.18
15:49
В Automation (интерфейс IDispatch) не предусмотрено штатных средств для реализации обращений к элементам массивов по индексам. Предусмотренные в Automation индексированные свойства допускают неоднозначность толкования и не поддерживаются встроенным языком 1С:Предприятия. Это значит, что для коллекций значений, не опознанных 1С:Предприятием как "свои" объекты, невозможно обращение к элементам по индексам из встроенного языка 1С:Предприятия. Однако, многие коллекции, в том числе и коллекции, определенные в 1С:Предприятии, поддерживают специальный интерфейс IEnumVARIANT, позволяющий совершить последовательный обход всех элементов коллекции. Этот механизм используется оператором Для Каждого ..., который имеется во многих языках программирования, в том числе и во встроенном языке 1С:Предприятия. Этот же механизм используется встроенным отладчиком 1С:Предприятия, когда он показывает элементы коллекции.
25 Dotoshin
 
30.01.18
15:52
(23) /// Как обойти все элементы структуры в 1с 8.3, 8.2

    Для Каждого Элемент Из ТвояСтруктура Цикл
        Сообщить(Элемент.Ключ + " " + Элемент.Значение);
    КонецЦикла;

Напиши то же самое на шарпе. или что-то мешает вместо "Для каждого" написать "foreach" ?
26 Скиурус
 
30.01.18
15:54
Ответ дан в (2) но автор видимо и C# так себе знает :(
27 Serg_1960
 
30.01.18
15:57
(17) Кажется я понял автора. Выполнить() может писать результат своей работы в объекты базы конфигурации, к которым позже можно будет обратиться через OLE. После этого эти объекты можно удалить(очистить).
28 FIXXXL
 
30.01.18
16:01
(27) Вычислить() возвращает результат
29 FIXXXL
 
30.01.18
16:03
(28) http://www.1s-portal.ru/index.php/stati/common-questions/9-introduction/111-execute-111.html#h1-vychislit
1.3. Операция конкатенации

загони ключи в строку и алга :)
30 Serg_1960
 
30.01.18
16:11
(28) Спасибо, я знаю :) Просто ранее я предложил использовать Выполнить(); автор обратил внимание на проблему с анализом результата; я с упорством, достойным лучшего применения, продолжаю искать варианты обхода ограничения... Я не упрямый - я упорный. Как баран. Не мешайте мне бодаться в ворота :))
31 Andy_Yuferov
 
30.01.18
16:31
(28) Я знаю, что она возвращает результат. Вы знаете, как с помощью Вычислить рассчитать функцию, в которую можно передать значение? Без объявления переменных. Я ведь не нахожусь в среде 1С! У меня есть только COM объект результата, который мне нужно преобразовать.
(29) А если ключом будет структура, или массив, или ещё какая-нибудь НЕХ? Соответствие же!
32 Andy_Yuferov
 
30.01.18
16:38
(26) Возможно. Иначе бы я не спрашивал. Интерфейс позволяет реализовать Next. Вы знаете, что там должно быть внутри Next? Я - нет, потому и спрашиваю.
33 Andy_Yuferov
 
30.01.18
16:40
(24) Спасибо. Я уже копаю в этом направлении.
34 FIXXXL
 
30.01.18
18:24
(31) (32) ТипЗнч() по очевидным НЕХ?
35 FIXXXL
 
30.01.18
18:25
(34) +Попытка
36 FIXXXL
 
30.01.18
18:26
(30) а если подряд ТРИ Выполнить()?
1. Инициализируем переменные
2. Присваиваем, основной код разбора НЕХ
3. Читаем результат

:)
37 FIXXXL
 
30.01.18
18:32
(36) хрен там :(
38 Andy_Yuferov
 
30.01.18
19:06
(37) Я так пробовал. Прежде чем на форум писать уж как только не извращался. Думал, может я дурак.
(34) ТипЗнч не работает из другой среды, увы. Является встроенной функцией языка.
39 FIXXXL
 
31.01.18
11:33
(38) ну тогда "трехзвенка" через промежуточную обработку разбора 1Сных НЕХ :)
Пользователь не знает, чего он хочет, пока не увидит то, что он получил. Эдвард Йодан