|
Удаление объектов в 1С при работе через COM (С#) | ☑ | ||
---|---|---|---|---|
0
Tezcatlipoka
16.06.16
✎
05:26
|
Всем добрый день. Прошу вашего совета.
Работаю с 1С через COM-соединение из внешнего приложения на C#. При попытке пометить на удаление элемент справочника "Файлы" вылетает с ошибкой "адресат вызова создал исключение" т.е. исключение возникает в самой 1С. (и через реквизит "ПометкаУдаления" и через функцию "УстановитьПометкуУдаления"). Причем такое поведение наблюдается только у данного справочника. Элементы других справочников без ошибок метятся на удаление. В конфигурацию никаких изменений не вносилось. Подключение к 1С идет через учетную запись администратора с полными правами. Из самой 1С файл метится на удаление без проблем. Так же, писал внешнюю обработку - файл так же метится без проблем. Пока приходится просто удалять файлы. Но это оставляет "битые ссылки" что может быть потенциально опасно для базы. Подскажите пожалуйста, в чем может быть проблема или хотя бы в каком направлении искать. Заранее, спасибо. Работаю в: 1С Предприятие 8.3.6.2421 Документооборот 8 КОРП 2.0.15.6 |
|||
1
Prog111
16.06.16
✎
05:49
|
(0) Случайно не предопределенные элементы справочника?
|
|||
2
varyag
16.06.16
✎
05:54
|
а у справочника в правах данного пользователя удаление есть?
|
|||
3
Tezcatlipoka
16.06.16
✎
06:22
|
В данном случае я пытаюсь работать с элементами справочника "Файлы".
Права есть - руками в настройках прав выставил полный доступ. |
|||
4
Tezcatlipoka
16.06.16
✎
06:25
|
Файлы с которыми я работаю я сам же и создаю через общий модуль РаботаСФайламиВызовСервера.СоздатьФайлНаОсновеФайлаНаДиске()
|
|||
5
catena
16.06.16
✎
06:33
|
(4)Может в справочнике что-то обрабатывается ПриЗаписи, ПередЗаписью?
|
|||
6
Tezcatlipoka
16.06.16
✎
06:43
|
Как я уже говорил выше - в конфигурацию изменений не вносилось и из самой 1С и внешних обработок объекты метятся. Так что там все стандартно.
|
|||
7
Prog111
16.06.16
✎
06:49
|
(6) Стандартно-то стандартно... Но возможно, что изначально прописано, что из формы помечаться может, а по соединению - какие-то условия не срабатывают. И покажи код, которым соединяешься.
|
|||
8
catena
16.06.16
✎
06:56
|
(6)Область действия кода могла быть не рассчитана на внешнее подключение.
|
|||
9
Tezcatlipoka
16.06.16
✎
06:58
|
Подключался двумя способами.
|
|||
10
Tezcatlipoka
16.06.16
✎
06:58
|
static void OldConnect()
{ dynamic connection; dynamic file; dynamic document; IV8COMConnector comConnector; Debug.WriteLine("Пытаемся подключиться к 1С."); try { comConnector = new COMConnector(); connection = comConnector.Connect(connectionStringTest); Debug.WriteLine("Успешное подключение."); } catch (Exception exception) { comConnector = null; connection = null; Debug.WriteLine("Ошибка подключения:" + exception.Message); } file = connection.Справочники.Файлы.НайтиПоКоду("00-00024399").ПолучитьОбъект(); Console.WriteLine(file.Наименование.ToString()); //file = connection.Справочники.Файлы.НайтиПоКоду("00-00024347").ПолучитьОбъект(); //document = connection.Справочники.ВнутренниеДокументы.НайтиПоКоду("0000-000950").ПолучитьОбъект(); file.УстановитьПометкуУдаления(true); //file.ПометкаУдаления = true; //file.Записать(); file = null; document = null; connection = null; comConnector = null; } |
|||
11
Tezcatlipoka
16.06.16
✎
06:59
|
static void NewConnect()
{ var v83ComConnector = Type.GetTypeFromProgID("V83.ComConnector"); var v83 = Activator.CreateInstance(v83ComConnector); object[] arguments = { "Srvr=\"" + serverT + "\";Ref=\"" + dataBaseT + "\";Usr=\"" + user + "\";Pwd=\"" + password + "\";" }; var x = v83ComConnector.InvokeMember("Connect", BindingFlags.Public| BindingFlags.InvokeMethod|BindingFlags.Static, null, v83, arguments); var br = GetObjectProperty(v83, x, "Справочники"); var files = GetObjectProperty(v83, br, "Файлы"); var fileRef = InvokeObjectMethod(v83, files, "НайтиПоКоду", new object[] { "00-00024399" }); var fileObj = InvokeObjectMethod(v83, fileRef, "ПолучитьОбъект", new object[] {}); var internalDocuments = GetObjectProperty(v83, br, "ВнутренниеДокументы"); //var intDocRef = InvokeObjectMethod(v83, internalDocuments, "НайтиПоКоду", new object[] { "0000-000953" }); //var intDocObj = InvokeObjectMethod(v83, intDocRef, "ПолучитьОбъект", new object[] {}); //var tmp = SetObjectProperty(v83, fileObj, "ПометкаУдаления", new object[] {true}); //var tmp2 = InvokeObjectMethod(v83, fileObj, "Записать", new object[] {}); var result = InvokeObjectMethod(v83, fileObj, "УстановитьПометкуУдаления", new object[] {true}); } public static object GetObjectProperty(object v83, object refObject, string propertyName) { return v83.GetType().InvokeMember(propertyName, BindingFlags.GetProperty, null, refObject, null); } public static object InvokeObjectMethod(object v83, object refObject, string methodName, object[] parameters) { return v83.GetType().InvokeMember(methodName, BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Instance , null, refObject, parameters); } public static object SetObjectProperty(object v83, object refObject, string propertyName, object[] parameters) { return v83.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, refObject, parameters); } |
|||
12
Tezcatlipoka
16.06.16
✎
07:03
|
Как можно видеть, пробовал работать с Внутренними документами и файлами. Внутренние документы без проблем метятся. Так же пробовал и с другими объектами справочников - они тоже метятся.
|
|||
13
Prog111
16.06.16
✎
07:14
|
file.УстановитьПометкуУдаления(true);
//file.ПометкаУдаления = true; //file.Записать(); Почему 2 последние строчки закомментированы? |
|||
14
arsik
гуру
16.06.16
✎
07:18
|
(12) Посмотри что пишется в журнале регистрации 1С.
|
|||
15
Провинциальный 1сник
16.06.16
✎
07:20
|
А если попробовать то же самое, но не из дотнета, а из другой базы 1с?
|
|||
16
Tezcatlipoka
16.06.16
✎
07:21
|
Потому что пробовал двумя способами пометить.
Первый - через УстановитьПометкуУдаления(true), а второй - через реквизит ПометкаУдаления и непосредственную запись объекта. В обоих случаях валится в ошибку с NullReferenceExeption. Журнал не смотрел. Сейчас взгляну. |
|||
17
Tezcatlipoka
16.06.16
✎
07:35
|
Попробовать из другой базы, конечно, можно. Но это ничего не даст. Речь о взаимодействии с 1С из внешнего приложения написанного на C#, так что от дотнета я все равно никуда не смогу уйти.
|
|||
18
Провинциальный 1сник
16.06.16
✎
07:38
|
(17) Как минимум, это даст более четкую локализацию проблемы
|
|||
19
Tezcatlipoka
16.06.16
✎
07:46
|
В журнале регистрации при ошибках пометки на удаление для файла появляется запись следующего содержания:
Событие: Данные.Изменение Статус транзакции:Отменена Метаданные: Регистр сведений. Дескрипторы доступа для файлов. |
|||
20
hhhh
16.06.16
✎
07:49
|
(19) значит прав нет на этот регистр сведений
|
|||
21
Tezcatlipoka
16.06.16
✎
07:57
|
Я работаю под админом с полными правами. Сейчас специально проверил - на этот регистр права на чтение, изменение, просмотр, редактирование и управление итогами.
|
|||
22
Nuobu
16.06.16
✎
09:34
|
Еще вариант: срабатывает подписка на событие, текст процедуры которой находится в модуле без галки "Внешнее подключение".
|
|||
23
Tezcatlipoka
16.06.16
✎
09:40
|
Благодарю. О варианте с подпиской не думал. Надо проверить.
|
|||
24
Tezcatlipoka
16.06.16
✎
10:44
|
Проблема решена.
В большинстве процедур и функций работы с файлами встречается вот такой кусочек кода который, собственно, и не давал помечать файл из COM: Если Источник.ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; D моем случае всегда у полученного объекта файла значение ОбменДанными.Загрузка было равно Ложь. Проблема решилась тривиально: dynamic file = connection.Справочники.Файлы.НайтиПоКоду("00-00024399").ПолучитьОбъект(); file.ОбменДанными.Загрузка = true; file.УстановитьПометкуУдаления(true, true); Всё работает, пометка ставится и снимается корректно. Всем огромное спасибо за советы и оперативную помощь. ) |
|||
25
hhhh
16.06.16
✎
19:45
|
(24) Источник.ОбменДанными.Загрузка должно быть Ложь. Вы не то нашли.
|
|||
26
КМ155
16.06.16
✎
20:15
|
(25) он то нашёл
|
|||
27
Torquader
16.06.16
✎
21:46
|
ОбменДанными.Загрузка=ИСТИНА переключает 1С в режим обязательной записи, то есть выключаются любые проверки корректности и т.п.
Конечно, таким образом, пометка удаления поставится, но, вполне вероятно, что в регистре "Регистр сведений. Дескрипторы доступа для файлов" были какие-то данные помечаемого файла, которые не позволяли это делать. И вот - данные остались, а файл - пометился. P.S. использование ОбменДанными.Загрузка даже выключает контроль уникальности кодов в справочнике - так что нужно быть очень аккуратным. |
|||
28
hhhh
16.06.16
✎
21:53
|
(26) он теперь везде будет лепить эту свою находку: Источник.ОбменДанными.Загрузка = Истина;
и у него и в проведении будет фигня и половина подписок не будет выполняться, потому что в подписках везде эта проверка. |
|||
29
Torquader
16.06.16
✎
22:41
|
(28) При установке ОбменДанными.Загрузка=ИСТИНА запись с проведением обычно не выполняется, но можно у документа поставить "Проведен=ИСТИНА" и просто записать, а потом удивляться - что это у нас вместо учёта в базе слово из четырёх букв.
|
|||
30
Tezcatlipoka
27.06.16
✎
04:28
|
Уважаемый hhhh - возможно, я не прав, используя Источник.ОбменДанными.Загрузка = Истина;
Но предложите тогда верное решение данной проблемы, если мое не верно. У всех получаемых мной файлов всегда Источник.ОбменДанными.Загрузка равно Ложь. И при таком значении данного атрибута функция записи файла для установки пометки удаления просто не сработает. |
|||
31
Serginio1
27.06.16
✎
06:45
|
void УничтожитьОбъект(object Объект)
{ Marshal.Release(Marshal.GetIDispatchForObject(Объект)); Marshal.ReleaseComObject(Объект); } ну и вызов УничтожитьОбъект(Object1C); Object1C = null; /// Можешь и не один GC.Collect(); GC.WaitForPendingFinalizers(); |
|||
32
hhhh
27.06.16
✎
07:51
|
(30) надо искать ошибку. Режим загрузка = Истина это выключение обычного режима работы программы. То есть лучше просто тогда непосредственно удалить - это будет меньше вреда для базы.
|
|||
33
DES
27.06.16
✎
09:09
|
а разве при работе через ком нельзя пройти момент удаления под отладчиком ?
|
|||
34
VensHak
27.06.16
✎
09:49
|
(30) также и я могу ошибаться, но проверьте из режима предприятия этот справочник. У элементов справочника есть реквизит "редактирует" где хранится имя пользователя, который не закрыл редактирование файла. И если реквизит не пустой, то пометить на удаление этот элемент нельзя.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |