Search
Write a publication
Pull to refresh

Работа с 1С 8.х из .Net приложений при помощи dynamic типов

Расскажу о себе и почему меня заинтересовала эта тема.

Меня зовут Андрей Бутенко и последние 3 года занимаюсь внедрением и разработкой под Microsoft Dynamics CRM 4.0/2011. В реалиях нашего рынка превалирующей по количеству внедрений учётной системой является 1C и рано или поздно люди, которые занимаются внедрением CRM систем сталкиваются с задачами интеграции/синхронизации данных между CRM и учётных систем (в частном случае 1C). Вот и передо мной эта задача тоже встала.

1С начиная с версии 8.0 предоставляет более-менее адекватный механизм работы с данными и метаданными системы — COM объект.

В качестве примера кода поставлю задачу создания в 1С контрагента и получения его кода.



Как работа с 1С выглядела до появления .Net Framework 4.0 и типа dynamic:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Type connector = Type.GetTypeFromProgID("V81.ComConnector");

if (connector == null)
throw new Exception(string.Format("COM Class Object {0} was not created or not registered in the system!", "V81.ComConnector"));

object connectorInstance = Activator.CreateInstance(connector);

if (connectorInstance == null)
throw new Exception(string.Format("Instance of class {0} was not created", "V81.ComConnector"));

//Подключение к базе
object _connection = connectorInstance.GetType().InvokeMember("Connect", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, connectorInstance, new object[] { "File=\"C:\\tmp\";" });

//Получение справочника контрагентов
object _dictionary = _connection.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, _connection, new object[] { "СправочникМенеджер.Контрагенты" });

//создание новой записи
object _record = _dictionary.GetType().InvokeMember("СоздатьЭлемент", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, _dictionary, null);

//Заполнение поля наименование
_record.GetType().InvokeMember("НаименованиеПолное", BindingFlags.Public | BindingFlags.SetProperty, null, _record, new object[] { "Наша тестовая организация" });

//Сохранение записи
_record.GetType().InvokeMember("Write", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, _record, null);

//Получение кода созданной организации
string code = _record.GetType().InvokeMember("Код", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static, null, _record, new object[] { }) as string;

//Выведение кода на консоль для проверки
Console.WriteLine(code);
Console.ReadKey();
}
}
}


Всё в принципе понятно, но такое количество рефлекссии на строку кода — немного ужасающе…

А теперь посмотрим тот же под, но написанный при помощи типов dynamic:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Type connector = Type.GetTypeFromProgID("V81.ComConnector");

if (connector == null)
throw new Exception(string.Format("COM Class Object {0} was not created or not registered in the system!", "V81.ComConnector"));

dynamic connectorInstance = Activator.CreateInstance(connector);

if (connectorInstance == null)
throw new Exception(string.Format("Instance of class {0} was not created", "V81.ComConnector"));

//Подключение к базе
dynamic _connection = connectorInstance.Connect("File=\"C:\\tmp\";");

//Получение справочника контрагентов
dynamic _dictionary = _connection.NewObject("СправочникМенеджер.Контрагенты");

//создание новой записи
dynamic _record = _dictionary.СоздатьЭлемент();

//Заполнение поля наименование
_record.НаименованиеПолное = "Наша тестовая организация";

//Сохранение записи
_record.Write();

//Получение кода созданной организации
string code = _record.Код as string;

//Выведение кода на консоль для проверки
Console.WriteLine(code);
Console.ReadKey();
}
}
}


И результаты работы обеих программ:

image

image
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.