gifts2017

Компонент (C#) Visual Studio для подключения к базе 1С Предприятия

Опубликовал Сергей Рудаков (fishca) в раздел Программирование - Внешние компоненты

Компонент для Visual Studio позволяет подключиться к базе 1С Предприятия, как в режиме COM-соединения, так в режиме Приложения либо с видимым интерфейсом, либо скрытым.
Прилагается небольшой пример подключения и получения списка справочников.

Свойства компоненты:

Active - bool - при установке в true подключается к базе 1С Предприятия

AppName1Cv8 - string - либо V81.Application либо V81.COMConnector

Database - string - имя базы данных на сервере 1С Предприятия

FilePath - string - каталог базы данных в файловом режиме

Password - string - пароль пользователя 1С Предприятия

Server - string - имя сервера 1С Предприятия

ThisConnect_Is_COM - bool - режим подключения к базе 1С либо V81.Application либо V81.COMConnector

UserName - string - пользователь под которым заходим в базу 1С

Visible1Cv8 - bool - признак показа инерфейса 1С Предприятия в режиме подключения V81.Application

Скачать файлы

Наименование Файл Версия Размер
- 484
.1244315087 34,47Kb
25.09.09
484
.1244315087 34,47Kb Скачать
- 144
.1244315132 51,40Kb
25.09.09
144
.1244315132 51,40Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. dushelov (Душелов) 07.06.09 14:05
Я бы еще добавил выбор платформы 7.7, 8.0, 8.1 и 8.2
2. dushelov (Душелов) 07.06.09 14:58
Ну а так же советую взять за основу мой класс для работы с объектами 1С (для 8-ки):

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Душелов._1C
{
public class Объект1С
{
[MarshalAs(UnmanagedType.IDispatch)] private object текущийОбъект;
public object ТекущийОбъект
{
[return: MarshalAs(UnmanagedType.IDispatch)]
get { return текущийОбъект;}
set { текущийОбъект = value; }
}

#region Init
public Объект1С()
{

}

public Объект1С(object ТекущийОбъект)
{
this.ТекущийОбъект = ТекущийОбъект;
}

~Объект1С()
{
try
{
Clear();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

internal void Clear()
{
if (ТекущийОбъект == null) return;
Marshal.Release(Marshal.GetIDispatchForObject(ТекущийОбъект));
Marshal.ReleaseComObject(ТекущийОбъект);
ТекущийОбъект = null;

GC.Collect();
GC.WaitForPendingFinalizers();
}
#endregion

public string Тип
{
get
{
return ВыполнитьФункцию("Метаданные").ВыполнитьФункцию("ПолноеИмя").ToString();
}
}

public Объект1С ПолучитьПараметр(string НаименованиеПараметра)
{
Object Результат = null;
try
{
Результат = ТекущийОбъект.GetType().InvokeMember(НаименованиеПараметра, BindingFlags.GetProperty, null, ТекущийОбъект, null);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}

return new Объект1С(Результат);
}

public Объект1С ВыполнитьФункцию(string НаименованиеФункции, Object[] Параметры)
{
Object Результат = null;
try
{
Результат = ТекущийОбъект.GetType().InvokeMember(НаименованиеФункции, BindingFlags.InvokeMethod, null, ТекущийОбъект, Параметры);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}

return new Объект1С(Результат);
}

public Объект1С ВыполнитьФункцию(string НаименованиеФункции)
{
Object Результат = null;
try
{
Результат = ТекущийОбъект.GetType().InvokeMember(НаименованиеФункции, BindingFlags.InvokeMethod, null, ТекущийОбъект, null);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}

return new Объект1С(Результат);
}

public void ВыполнитьПроцедуру(string НаименованиеПроцедуры)
{
try
{
ТекущийОбъект.GetType().InvokeMember(НаименованиеПроцедуры, BindingFlags.InvokeMethod, null, ТекущийОбъект, null);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}

public override string ToString()
{
return ТекущийОбъект != null ? ТекущийОбъект.ToString() : "Объект 1С";
}
}
}
3. Сергей Рудаков (fishca) 07.06.09 20:05
Спасибо за комментарий, учту!
4. ValentinV (ValentinV) 07.06.09 23:09
По-мужски закончили. ПЛЮС.
5. dushelov (Душелов) 07.06.09 23:16
(3) Так же можно добавить тест подключения, и дальше получить структуру метаданных...
6. Сергей Видякин (badboychik) 08.06.09 01:28
было бы супер сделать компонент DataAdapter1С , чтобы к нему можно было привязывать сетки, DataAware-компоненты... было бы круто!
7. Сергей Рудаков (fishca) 08.06.09 08:50
(5) не очень понял, что значит тест подключения. В студии когда ставишь активность истина, как раз происходит подключение. Единственное структуру метаданных не выдает :)
8. Сергей Рудаков (fishca) 08.06.09 08:51
(6) что этот компонент должен делать и как к нему можно было бы привязывать сетки, DataAware-компоненты?
9. dushelov (Душелов) 08.06.09 09:21
(8) тоже делать, что и любой датаадаптер ;)
10. Сергей Рудаков (fishca) 08.06.09 09:32
(9) мне больше непонятно что значит привязывать сетки...
11. Сергей Видякин (badboychik) 08.06.09 15:35
ну в .Net есть 4 встроенных провайдера - OLE,ODBC,MSSQL,Oracle. Сторонними разработчиками например сделан провайдер для FireBird. Вот и для 1С можно было бы сделать. В идеале - чтоб можно было визуальным мастером создавать ДатаСет и выбирать в него таблицы как они есть в метаданных 1С - "Справочник.Номенклатура" например или сразу несколько документов и справочников.
Плюсы - можно сделать быстрого клиента. Например, я делал на c# (обычным способом через СОМ) форму подбора номенклатуры - в 1С медленно ищется товар среди 10000 позиций когда набираешь код на клавиатуре, а в этом клиенте практически мгновенно. Можно и документ создавать из клиента, но до этого руки не дошли. Можно например сделать параллельную БД (на MSSQL ЕЕ хотя б) и там хранить дополнительные реквизиты (любых объектов), если не хочется нетиповую конфигурацию. Через клиента можно работать с "расширенной" конфигой, а в 1С все "типовое" :) Но это уже полет мысли :)
12. Сергей Рудаков (fishca) 08.06.09 16:07
(11) может выложишь обработку для примера?
Constantine Grey; +1 Ответить
13. Сергей Видякин (badboychik) 08.06.09 16:44
она на работе кажется осталась, давно это было... а щас новую некогда писать... через пару дней возможно сделаю..
14. Сергей Видякин (badboychik) 08.06.09 20:02
а, я нашел все таки:
СОЕДИНЕНИЕ:
v8connector = Type.GetTypeFromProgID("V81.COMConnector");
v8inst = Activator.CreateInstance(v8connector);
object[] arg = new object[] { @"File='" + txtPath.Text + "'; Usr ='" + txtLogin.Text + "';Pwd='" + txtPass.Text + "';" };
// Соединяемся
v8 = v8connector.InvokeMember("Connect", BindingFlag, null, v8inst, arg);

ПРИМЕР ВЫПОЛНЕНИЯ ЗАПРОСА:
// Создаем запрос
object Q = v8inst.GetType().InvokeMember("NewObject", BindingFlag, null, v8, new object[] { "Запрос" });
// Присваиваем свойству ТЕКСТ текст запроса
SetObjectProperty(Q, "Текст",txtQuery.Text);
// Выполняем!
object QResult = DoObjectMethod(Q, "Выполнить", null);
// Достаем объект "Колонки" и их число
object Cols = GetObjectProperty(QResult, "Колонки");
int NumCol = (int)DoObjectMethod(Cols, "Количество", null);

ОБЕРТКА ДЛЯ ПОЛУЧЕНИЯ/УСТАНОВКИ СВОЙСТВ и ВЫПОЛНЕНИЯ МЕТОДОВ 1С:
// Функция чтения свойства
public object GetObjectProperty(object refObject, string propertyName)
{
return v8inst.GetType().InvokeMember(propertyName, BindingFlags.GetProperty, null, refObject, null);
}
// Функция установки свойства
public object SetObjectProperty(object refObject, string propertyName, object value)
{
object[] arg = new object[] { value };
return v8inst.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, refObject, arg);
}
// Функция выполнения метода
public object DoObjectMethod(object refObject, string methodName, object[] args)
{
return v8inst.GetType().InvokeMember(methodName, BindingFlag, null, refObject, args);
}

В принципе этого хватит чтоб написать любое взаимодействующее с 1С приложение. И без всяких маршаллингов :)
15. dushelov (Душелов) 08.06.09 21:10
(14) См. (2)

Маршалинг нужен, как я столкнулся, в случае с 7-кой, когда она не отрабатывала, как положено ряд объектов, типа булево, к примеру, или Null.
16. dushelov (Душелов) 08.06.09 21:11
+15 и не надо забывать про очистку памяти, иначе 1С-ка так и будет болтаться в памяти и жрать ресурсы.
17. Сергей Рудаков (fishca) 08.06.09 22:25
(14) у меня в компоненте так и сделано :)
В примере с получением справочников как раз вызывается InvokeMember(propertyName, BindingFlags.GetProperty...);
18. Oleg Olenin (oleo) 08.09.09 11:56
2badboychik: а для непримитивных значений реквизитов (например ссылка на запись в справочнике) public object SetObjectProperty работает?

19. Oleg Olenin (oleo) 08.09.09 11:59
2dushelov: я прошу прощение, а где в вашем примере метод аналогичный SetObjectProperty? Может я чего просмотрел? И если не сложно, такой же вопрос как в п18 - работает не работает?
20. dushelov (Душелов) 08.09.09 13:21
(19) Функция, аналогичная "ПолучитьПараметр", флаг меняется с GetProperty на SetProperty
21. Oleg Olenin (oleo) 08.09.09 14:13
(20) Спасибо за ответ! Для присваивания в качестве значения поля ссылки на другой объект 1С все проходит нормально?
22. dushelov (Душелов) 08.09.09 15:02
23. Лев Моисеев (Lemoi) 12.03.10 10:41
Кто-нибудь знает, можно ли подключившись из .NET к 1С 8.1 по COM вызвать оператор "Выполнить" с текстом выполняемых действий? И как это сделать?
24. dushelov (Душелов) 12.03.10 10:49
(23) Никак.
Только вызвать функцию общего модуля или модуля внешнего соединения, где используется эта команда.
25. Лев Моисеев (Lemoi) 12.03.10 11:28
26. Алексей Антонов (Katavary) 08.04.10 09:39
Не понятно как можно получить например цены товара из номенклатуры, или изображение товара. Возможно ли это?
Если кто знает подскажите пожалуйста. а еще лучше примерчик...
27. Алексей Антонов (Katavary) 08.04.10 11:25
вызываю такой код:

Object Directories = GetObjectProperty(COMobj, "Справочники");
Object Nomenclature = GetObjectProperty(Directories, "Номенклатура");
Object docSelection_ = InvokeObjectMethod("Выбрать", Nomenclature);
InvokeObjectMethod("Следующий", docSelection_)

Object name = GetObjectProperty(docSelection_, "Наименование");
Object obj = v81.InvokeMember("ОсновноеИзображение", BindingFlags.GetProperty, Type.DefaultBinder, docSelection_, new Object[] { });

С переменной name вроде понятно, это строка, наименовани. А как теперь работать с переменной obj?
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа