1с получитьcomобъект расширение имени файла задано неверно
Использование COM-соединения, выгрузка в Excel через COM-объект Excel.Application
Вообще COM-объекты используют для соединения информационной базы 1С с файлом Word, Excel, Outlook или любой другой программой, поддерживающей данный интерфейс обмена данными. В этой статье рассмотрим задачу выгрузки/загрузки данных из/в MS Excel. Чтобы это осуществить воспользуемся COM-соединением и объектом Excel.Application. Для примера возьмём задачу выгрузки/загрузки данных о номенклатуре. Пример рассмотрим ниже.
COM-соединение
Что же такое COM-соединение? Component Object Model (или COM) – это технология (фирмы Microsoft) взаимодействующих компонентов, которые одновременно могут быть использованы в разных приложениях. При этом весь функционал соответствующего компонента наследуется внутрь разрабатываемого приложения. В нашем случае COM-объект Excel.Application используется внутри кода 1С для операций с файлом книги MS Excel.
Объект Excel.Application
У объекта Excel.Application существует ряд методов, которые нам могут пригодиться для реализации нижепоставленной задачи:
- ОбъектExcel.WorkBooks.Open(ИмяФайла) – Открытие книги MS Excel
- ОбъектExcel.ActiveWorkbook.Close() – Закрытие текущей книги
- ОбъектExcel.Quit() – Закрытие COM-объекта
- ОбъектExcel.Sheets(ИмяЛиста) – Получает лист книги
- ЛистExcel.Cells(НачалоСтрока, НачалоСтолбец) – Ячейка таблицы на данном листе
- ЛистExcel.Range(Ячейка1, Ячейка2) – Выделенная область
- ЯчейкаExcel.Value – Значение ячейки таблицы
- ЯчейкаExcel.Text – Текст ячейки таблицы
Постановка задачи
Итак, предположим, что в обработке 1С у нас имеется табличная часть, состоящая из следующих колонок:
Необходимо реализовать 2 функционала (сделать на форме 2 основные кнопки):
- Выгрузка табличной части в подготовленный файл MS Excel
- Загрузка табличной части из файла.
Алгоритм выгрузки/загрузки в MS Excel
Алгоритм выгрузки следующий:
- Выгружаем табличную часть в таблицу значений
- Создаём новый COM-объект Excel.Application
- Выбираем файл, открываем файл книги MS Excel
- Переходим на заданный лист книги
- Выгружаем данные в файл
- Закрываем книгу, выходим из COM-объекта.
Алгоритм загрузки следующий:
- Создаём новый COM-объект Excel.Application
- Выбираем файл, открываем файл книги MS Excel
- Переходим на заданный лист книги
- Загружаем данные из файла в таблицу значений
- Закрываем книгу, выходим из COM-объекта
- Таблицу значений выгружаем в табличную часть.
Операция выгрузки и загрузки данных о номенклатуре происходит в заранее подготовленный шаблон MS Excel.
Пример кода 1С
Код 1С я постарался разделить на отдельные функции, чтобы, скопировав, с ними можно было работать где угодно. На форме обработки 1С были созданы 3 кнопки:
В итоге в реализации алгоритма получились следующие основные процедуры и функции 1С:
- ПолучитьExcel – Получает COM-объект MS Excel;
- ЗакрытьExcel – Закрывает использование COM-объекта MS Excel;
- ПолучитьЛистExcel – Получает лист книги Excel;
- ДобавитьТабличныйДокументВExcel – Добавляет табличный документ на лист Excel (нужно для выгрузки данных);
- ПрочитатьОбластьИзExcel – Читает область ячеек с листа Excel (нужно для загрузки данных);
- ШиринаЛистаExcel – Ширина листа Excel;
- ВысотаЛистаExcel – Высота листа Excel;
- ПреобразоватьТДвТЗ – Преобразует табличный документ в таблицу значений;
- ПреобразоватьТЗвТД – Преобразует таблицу значений в табличный документ;
Для начала приведу вспомогательную функцию для открытия/сохранения файла на диске:
Также в реализации алгоритма были задействованы следующие вспомогательные функции:
// Преобразует в массив переменную любого типа данных. // // Параметры: // Объект - Произвольный - произвольный объект данных; // Проверка - - Осуществление проверки на заполненное значение. // // Возвращаемое значение: // - Массив с теми же данными. // Функция ПреобразоватьВМассив(Объект, Проверка = Ложь) Экспорт ОбъектМассив = Новый Массив; Если НЕ Проверка ИЛИ ЗначениеЗаполнено(Объект) Тогда Если ТипЗнч(Объект) = Тип("Массив") Тогда ОбъектМассив = Объект; ИначеЕсли ТипЗнч(Объект) = Тип("СписокЗначений") Тогда ОбъектМассив = Объект.ВыгрузитьЗначения(); ИначеЕсли ТипЗнч(Объект) = Тип("Строка") Тогда ОбъектМассив = РазобратьСтрокуВМассивПоРазделителю(Объект); ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда Для Каждого Элемент Из Объект Цикл ОбъектМассив.Добавить(Элемент.Значение); КонецЦикла; Иначе ОбъектМассив.Добавить(Объект); КонецЕсли; КонецЕсли; Возврат ОбъектМассив; КонецФункции;
// Разбирает строку в массив подстрок по разделителю. // При этом пробелы между подстроками не учитываются. // // Параметры: // Стр - исходная строка; // СтрРазделитель - разделитель, по умолчанию ","; // ИгнорироватьПустые - игнорировать ли пустые места между разделителями. // // Возвращаемое значение: // Массив строк // Функция РазобратьСтрокуВМассивПоРазделителю(Знач Стр, СтрРазделитель = ",", ИгнорироватьПустые = Ложь) Экспорт Результат = Новый Массив; ВхождениеРазделителя = Найти(Стр, СтрРазделитель); Пока ВхождениеРазделителя <> 0 Цикл ЧастьДоРазделителя = СокрЛП(Лев(Стр, ВхождениеРазделителя - 1)); Если НЕ (ИгнорироватьПустые И ПустаяСтрока(ЧастьДоРазделителя)) Тогда Результат.Добавить(ЧастьДоРазделителя); КонецЕсли; Стр = СокрЛП(Сред(Стр, ВхождениеРазделителя + 1)); ВхождениеРазделителя = Найти(Стр, СтрРазделитель); КонецЦикла; Если НЕ (ИгнорироватьПустые И ПустаяСтрока(Стр)) Тогда Результат.Добавить(СокрЛП(Стр)); КонецЕсли; Возврат Результат; КонецФункции;
// Создаёт новую таблицу значений с заданными колонками. // // Параметры: // пКолонки - , , , , - // Набор колонок для таблицы значений. // // Возвращаемое значение: // - Созданная таблица. // Функция ПолучитьТаблицуВывода(пКолонки) Экспорт ТЗ = Новый ТаблицаЗначений; Если пКолонки <> Неопределено Тогда Если ТипЗнч(пКолонки) = Тип("Строка") Тогда пКолонки = РазобратьСтрокуВМассивПоРазделителю(пКолонки); КонецЕсли; Если ТипЗнч(пКолонки) = Тип("Структура") Тогда Для Каждого Поле Из пКолонки Цикл СтрокаТабл = ТЗ.Колонки.Добавить(Поле.Ключ, Поле.Значение); КонецЦикла; ИначеЕсли ТипЗнч(пКолонки) = Тип("СписокЗначений") Тогда Для Каждого Поле Из пКолонки Цикл Если Поле.Пометка Тогда СтрокаТабл = ТЗ.Колонки.Добавить(Поле.Значение, пКолонки.ТипЗначения, Поле.Представление); КонецЕсли; КонецЦикла; ИначеЕсли ТипЗнч(пКолонки) = Тип("ТаблицаЗначений") Тогда ЕстьНаименование = (пКолонки.Колонки.Найти("Наименование") <> Неопределено); ЕстьТипЗначения = (пКолонки.Колонки.Найти("ТипЗначения") <> Неопределено); ЕстьЗаголовок = (пКолонки.Колонки.Найти("Заголовок") <> Неопределено); ЕстьШирина = (пКолонки.Колонки.Найти("Ширина") <> Неопределено); Для Каждого Поле Из пКолонки Цикл СтрокаТабл = ТЗ.Колонки.Добавить(?(ЕстьНаименование, Поле.Наименование, ""), ?(ЕстьТипЗначения, Поле.ТипЗначения, Новый ОписаниеТипов), ?(ЕстьЗаголовок, Поле.Заголовок, ""), ?(ЕстьШирина, Поле.Ширина, 0)); КонецЦикла; Иначе Для Каждого Поле Из пКолонки Цикл СтрокаТабл = ТЗ.Колонки.Добавить(Поле); КонецЦикла; КонецЕсли; КонецЕсли; Возврат ТЗ; КонецФункции;
// Создаёт структуру колонок из таблицы значений. // // Параметры: // ТабЗначений - - Любая таблица. // // Возвращаемое значение: // - Созданная таблица. // Функция ПолучитьСтруктуруКолонокИзТаблицы(ТабЗначений) Экспорт СтруктураКолонок = Новый Структура; Для Каждого ЭлементКолонка Из ТабЗначений.Колонки Цикл СтруктураКолонок.Вставить(ЭлементКолонка.Имя, ЭлементКолонка.ТипЗначения); КонецЦикла; Возврат СтруктураКолонок; КонецФункции;
Основные функции обработки алгоритма следующие:
// Записывает данные из табличного документа в файл MS Excel. // // Параметры: // ЛистExcel - - Лист из файла MS Excel; // Таблица - - Документ, по порядку следования колонок и строк // соответствующий листу файла MS Excel; // Шапка - - Количество первых строк для шапки в файле MS Excel; // СписокСтолбцов - , - Список номеров столбцов, которые будут выгружены // в файл MS Excel; // СписокСтрокЗапрета - , - Список номеров строк, которые не должны // выгружаться в файл MS Excel. Если этот параметр не задан, то выгружаются все строки; // ПроверятьЗначения - - Определяет будут ли проверяться ячейки табличного // документа на содержание в них значения, а не текстовое представление этого значения. // По умолчанию этот параметр "Ложь". // Процедура ДобавитьТабличныйДокументВExcel(ЛистExcel, Таблица, Шапка, СписокСтолбцов, СписокСтрокЗапрета = Неопределено, ПроверятьЗначения = Ложь) Экспорт Если ТипЗнч(СписокСтолбцов) = Тип("Строка") Тогда СписокСтолбцов = РазобратьСтрокуВМассивПоРазделителю(СписокСтолбцов); КонецЕсли; Если ТипЗнч(СписокСтрокЗапрета) = Тип("Строка") Тогда СписокСтрокЗапрета = РазобратьСтрокуВМассивПоРазделителю(СписокСтрокЗапрета); КонецЕсли; ЕстьМассив = (СписокСтрокЗапрета = Неопределено); Если ЕстьМассив Тогда Попытка МассивCOM = Новый COMSafeArray("VT_VARIANT", 1, Таблица.ВысотаТаблицы - Шапка); Исключение ЕстьМассив = Ложь; КонецПопытки; КонецЕсли; Для Каждого НомерСтолбца Из СписокСтолбцов Цикл Для НомерСтроки = Шапка+1 По Таблица.ВысотаТаблицы Цикл Если СписокСтрокЗапрета = Неопределено ИЛИ (СписокСтрокЗапрета.Найти(Строка(НомерСтроки)) = Неопределено И СписокСтрокЗапрета.Найти(Число(НомерСтроки)) = Неопределено) Тогда Область = Таблица.Область(НомерСтроки, Число(НомерСтолбца)); Значение = ?(ПроверятьЗначения И Область.СодержитЗначение, Область.Значение, Область.Текст); Если ЕстьМассив Тогда МассивCOM.SetValue(0, НомерСтроки-Шапка-1, Значение); Иначе ЛистExcel.Cells(НомерСтроки, Число(НомерСтолбца)).Value = Значение; КонецЕсли; КонецЕсли; КонецЦикла; Если ЕстьМассив Тогда ЛистExcel.Range(ЛистExcel.Cells(Шапка+1, Число(НомерСтолбца)), ЛистExcel.Cells(Таблица.ВысотаТаблицы, Число(НомерСтолбца))).Value = МассивCOM; КонецЕсли; КонецЦикла; КонецПроцедуры;
// Читает область ячеек из MS Excel в табличный документ. // // Параметры: // ЛистExcel - - Лист из файла MS Excel; // ТабДок - - Исходный табличный документ, поле табличного // документа или таблица значений. Если этот параметр не задан, то создаётся // новый табличный документ; // НачалоСтрока - - Начальная строка в файле MS Excel; // НачалоСтолбец - - Начальный столбец в файле MS Excel; // КонецСтрока - - Конечная строка в файле MS Excel; // КонецСтолбец - - Конечный столбец в файле MS Excel. // // Возвращаемое значение: // - Возвращает прочитанный из области в MS Excel табличный // документ, который передавался в эту функцию параметром "ТабДок". // Функция ПрочитатьОбластьИзExcel(ЛистExcel, ТабДок = Неопределено, НачалоСтрока, НачалоСтолбец, КонецСтрока, КонецСтолбец) Экспорт Если ТабДок = Неопределено Тогда ТабДок = Новый ТабличныйДокумент; КонецЕсли; Попытка МассивCOM = Новый COMSafeArray("VT_VARIANT", КонецСтолбец - НачалоСтолбец + 1, КонецСтрока - НачалоСтрока + 1); ЕстьМассив = Истина; Исключение ЕстьМассив = Ложь; КонецПопытки; Если ЕстьМассив Тогда МассивCOM = ЛистExcel.Range(ЛистExcel.Cells(НачалоСтрока, НачалоСтолбец), ЛистExcel.Cells(КонецСтрока, КонецСтолбец)).Value; Для ИндексКолонка = НачалоСтолбец По КонецСтолбец Цикл Для ИндексСтрока = НачалоСтрока По КонецСтрока Цикл Значение = МассивCOM.GetValue(ИндексКолонка - НачалоСтолбец + 1, ИндексСтрока - НачалоСтрока + 1); ТабДок.Область(ИндексСтрока, ИндексКолонка).СодержитЗначение = Истина; ТабДок.Область(ИндексСтрока, ИндексКолонка).Значение = Значение; КонецЦикла; КонецЦикла; Иначе Для ИндексКолонка = НачалоСтолбец По КонецСтолбец Цикл Для ИндексСтрока = НачалоСтрока По КонецСтрока Цикл Значение = ЛистExcel.Cells(ИндексСтрока, ИндексКолонка).Value; ТабДок.Область(ИндексСтрока, ИндексКолонка).СодержитЗначение = Истина; ТабДок.Область(ИндексСтрока, ИндексКолонка).Значение = Значение; КонецЦикла; КонецЦикла; КонецЕсли; Возврат ТабДок; КонецФункции;
// Преобразовать таблицу значений в табличный документ. // // Параметры: // ТабЗначений - - Исходная таблица значений; // ТабДок - - Полученный табличный документ. Если параметр не задан, // то документ создаётся заново и возвращается функцией; // НачалоСтрока - - Строка начала области; // НачалоСтолбец - - Столбец начала области; // ВыводитьЗаголовки - - Определяет выводить ли имена колонок или нет. // // Возвращаемое значение: // - Полученный табличный документ (возвращает параметр "ТабДок"). // Функция ПреобразоватьТЗвТД(ТабЗначений, ТабДок = Неопределено, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, ВыводитьЗаголовки = Ложь) Экспорт Если ТабДок = Неопределено Тогда ТабДок = Новый ТабличныйДокумент; КонецЕсли; // Определение габаритов таблицы НачалоСтрока = ?(НачалоСтрока = Неопределено, 1, НачалоСтрока); НачалоСтолбец = ?(НачалоСтолбец = Неопределено, 1, НачалоСтолбец); // Преобразование ИндексСтроки = НачалоСтрока; Если ВыводитьЗаголовки Тогда ИндексКолонки = НачалоСтолбец; Для Каждого Колонка Из ТабЗначений.Колонки Цикл ТабДок.Область(ИндексСтроки, ИндексКолонки).Текст = ?(ПустаяСтрока(Колонка.Заголовок), Колонка.Имя, Колонка.Заголовок); ИндексКолонки = ИндексКолонки + 1; КонецЦикла; ИндексСтроки = ИндексСтроки + 1; КонецЕсли; Для Каждого Элемент Из ТабЗначений Цикл ИндексКолонки = НачалоСтолбец; Для Каждого Колонка Из ТабЗначений.Колонки Цикл ТабДок.Область(ИндексСтроки, ИндексКолонки).СодержитЗначение = Истина; ТабДок.Область(ИндексСтроки, ИндексКолонки).ТипЗначения = Новый ОписаниеТипов(Колонка.ТипЗначения); ТабДок.Область(ИндексСтроки, ИндексКолонки).Значение = Элемент[Колонка.Имя]; ИндексКолонки = ИндексКолонки + 1; КонецЦикла; ИндексСтроки = ИндексСтроки + 1; КонецЦикла; Возврат ТабДок; КонецФункции;
В реализации алгоритма был дополнительно использован объект COMSafeArray с типом VT_VARIANT. Этот COM-объект выступает в качестве двумерного массива, в котором удобно хранить значения ячеек. Также использование данного объекта повышает быстродействие операций чтения/записи для ячеек таблицы.
Целиком получившуюся обработку 1С, а также шаблон для загрузки/выгрузки можно скачать по ссылке ниже.
Указанные здесь процедуры и функции я постарался сделать универсальными. Они могут быть применены для широкого круга прикладных задач.
а нужно чтобы обработка искала файлы в определенной
директории, потом обращалась через ком объект к ниму
вот вообщем и все. Сейчас именно проблема обратиться к файлу как COM Объекту.
html не более чем разметка, о каком com-е идет речь? :D Подозреваю, что вам просто нужно распарсить html. в конфигураторе F1 поиск DOM.
про поиск файлов - тоже поиск в справке - НайтиФайлы
Поиск файлов и весь основной функционал парсинга реализованы уже
Просто сейчас я помещаю html файл в табличное поле на форме обрабтки
потом обращаюсь к нему ЭлементыФормы.ПолеHTMLДокумента2.Перейти("D:\имя.htm");
и дальше работаю с ним через ком объект. Просто для работы таким образом
через элементы формы обращаться к HTML документу неудобно. Сейчас я делаю
чтобы обработка выбирала файлы из каталога перебирала их по одному получала
СОМ объект для каждого файла. Перебор это ерунда, его я уже сделал
основная проблема получить СОМ объект. Пробовал ConHTML = ПолучитьCOMОбъект(ФайлHTML.ПолноеИмя)
1С ругается на раширение файла
"ПолеHTMLДокумента.Документ
ПолеHTMLДокумента (HTMLDocumentField)
Документ (Document)
Использование:
Только чтение.
Описание:
Тип: COMОбъект. Предоставляет доступ к HTML документу.
Описание объекта, в целом, определяется стандартом"
(3) я же написал, что html не более чем разметка, почитайте справку, посмотрите типовую обработку "Обозреватель" (кажется так называется), если удобно так, то считывайте html как текст, затем методом УстановитьТекст()
ConHTML = ПолучитьCOMОбъект(ФайлHTML.ПолноеИмя) - возвращает com объект по названию
ПолеHTMLДокумента.Документ
ПолеHTMLДокумента (HTMLDocumentField)
Документ (Document)
Использование:
Только чтение.
Описание:
Тип: COMОбъект. Предоставляет доступ к HTML документу.
Описание объекта, в целом, определяется стандартом" - это уже сам COMобъект.
Смотри описание функций и процедур ПолеHTMLДокумента
ConHTML = ПолучитьCOMОбъект(ФайлHTML.ПолноеИмя) - возвращает com объект по названию
Такой результат. Этот метод я пытался использовать в самом начале
: Ошибка при вызове метода контекста (ПолучитьCOMОбъект)
ConHTML = ПолучитьCOMОбъект(ФайлHTML.ПолноеИмя);
по причине:
Ошибка получения объекта COM: Расширение имени файла задано неверно
А как можно получить ОболочкаHTMLДокумента
Нашел решение если кому интересно
МассивФайлов = НайтиФайлы(ЭлементыФормы.ПолеВвода1.Значение, "*");
Для Каждого ФайлHTML Из МассивФайлов Цикл
Сообщить(ФайлHTML.ПолноеИмя);
objIE = Новый COMОбъект("InternetExplorer.Application");
objIE.Navigate(ФайлHTML.ПолноеИмя);
ТелоДокумента = objIE.Document.body;
МассивTBODY = ТелоДокумента.getElementsByTagName("TBODY");
Основной код
(7) Честно говоря никому не интересно. Тоже самое можно сделать и через ПолеHtmlДокумента. и к тому же лучше делать objIE.Visible = false , а создавать в цикле objIE это вообще жесть, вынеси из цикла
да и все еще название темы меня пугает. COM для html это что-то странное. objIE или ПолеHtmlДокумента это не html. это оболочки над IE, использующие в том числе com технологию для взаимодействия.
Для будущих html-разбирателей - советую использовать следующий набор инструментов
fiddler, firebug+firepath+mozzila, tidy, curl
Основная идея сводить с помощью tidy html в xml и получать нужную информацию через xpath. есть еще htmlquery, который доступен по com.
Windows 2008 R2, MS SQL 2008, 1c 8.3.4.437. Агент запускается от пользователя USR1CV который имеет права администратора. Установлен MS office 2010.
Если использовать:
Файл = Новый Файл(ВремФайл);
Файл.Удалить();
Не находить процедуру Удалить().
Видимо дело в правах и доступе, но не пойму, где забыл открыть доступ.
(1) tiz7, Вынесете работу с COM объектом в отдельный серверный модуль, без передачи ссылок этого объекта на клиент. COM объекты не работают в контексте управляемой формы
Вот пример работает на файловой базе, но не работает на серверной.
Шаблон Active document типа word 97-2003 и содержит текст [Дата].
ОболочкаActiveDocument.Записать (ActiveDocumentShell.Write)
ОболочкаActiveDocument (ActiveDocumentShell)
Записать (Write)
Синтаксис:
Тип: Строка.
Имя файла, в который необходимо записать Active document. Если файл существует, он будет перезаписан, иначе - создан.
Описание:
Записывает Active document в файл.
(15) AlX0id, даже если попытаться получить уже готовый файл (сохраненный файл руками в определенном месте) и открывать ПолучитьCOMОбъект("C:\DATA\DATA.doc") все равно такая же ошибка(
(16) tiz7, Воспользуйтесь другой функцией работы с COM объектом
О = Новый COMОбъект()
O.Open
.
И второе вынесете код работы с COM объектом во внешний модуль
Если работа идёт в режиме управляемых форм, то перед началом функции, которая вызывает ПолучитьCOMОбъект() должно стоять НаСервере.
Файл = Новый Файл(ВремФайл);
Файл.Удалить();
Такой файл удалить нельзя, так как он не сохранён. Его можно только Файл.Закрыть();
Все это работало до на другом сервере и в серверной базе. Просто видимо забыл про какие то права пользователя(
Был такой случай. Отлично работало до переустановки сервера MS+1C после падения. Всё было установлено в штатном режиме тем же сисадмином. Никакие проверки и поиски закрытых ресурсов не помогали. Всё прошло только после переустановки сервера.
Переустановил от имени того пользователя Office не помогло( И процесса WINWORD.EXE появляется в списке процессов же. Видимо запускается. но что то мешает открывать файлы.
(9) tiz7, Откройте в самом ком объекте файл, он должен сразу же вызвать исключение с расшифровкой ошибки. И кстати при выполнении вашего кода офис не может распознать открываемый файл и выдает исключение что это не файл офиса. Нужно создавать пустой файл в самом ворде и записывать его во временный файл.
на сервере, службы компонентов - настройка DCOM - находим нужную компоненту, заходим в нее, закладка удостоверение, в указанный пользователь вводим USR1CV(ну или какой у Вас) и пароль конечно
По сабжу:
Кажется нет некоторых прав на директорию. Попробуйте создать временный файл и удалить его. Вопрос скорее к администраторам.
Да как-бы пофиг. Главное под какой учеткой сервер 1С крутится.
Околосабж:
Я так понял нужно MS Office документы создавать? С моей точки зрения не очень хорошо ставить офисный пакет на сервер БД.
Можно и без офиса документы то создавать, вот вордовский http://infostart.ru/public/16215/ так-же и с экселем легко найти. Лицензия жеж, деньги жеж. Кстати чтение из excel "летаить", если читать драйвером ODBC.\ и SQL запросы можно ! Ня!
даже если попытаться получить уже готовый файл (сохраненный файл руками в определенном месте) и открывать ПолучитьCOMОбъект("C:\DATA\DATA.doc") все равно такая же ошибка(
А кто владелец файла то? Что-то мне подсказывает что владелец - ваша учетка, а сервер читает под другой и правьев нет. Вы не поленитесь перед скармливанием файла алгоритму - права но доступ ручками на файл дать.
Чем отличается "ПолучитьCOMОбъект" от "Новый COMОбъект"? И в каких случаях нужно каждый отдельно использовать? В синтаксисе помощника читал, но я ничего вообще не понял.
(5)Хорошо. Давайте разберем написанное в синтаксис-помощнике вместе.
Глобальный контекст (Global context)
ПолучитьCOMОбъект (GetCOMObject)
Синтаксис:
ПолучитьCOMОбъект(, )
Параметры:
(необязательный)
Тип: Строка.
Имя файла, включающее полный путь.
(необязательный)
Тип: Строка.
Имя класса COM, экземпляр которого должен быть создан или получен. Если расширение имени файла, указанное в первом параметре, полностью идентифицирует класс объекта, то параметр может быть опущен.
Возвращаемое значение:
Тип: COMОбъект.
Описание:
Основное применение функции ПолучитьCOMОбъект - это получение COM-объекта, соответствующего файлу. Для этого следует в качестве первого параметра функции задать имя файла, который будет определять COM-объект. Например, фрагмент кода:
Таб = ПолучитьCOMОбъект("C:\DATA\DATA.XLS");
создает объект Excel.Application и открывает с его помощью файл документа "C:\DATA\DATA.XLS". Если указанный файл во время выполнения данного фрагмента уже открыт с помощью MS Excel, то будет получена ссылка на уже существующий объект.
Для файлов, указываемых в качестве параметра данной функции, должно быть установлено соответствие расширения имени файла и класса COM.
Если в качестве имени файла указана пустая строка, то будет создан новый экземпляр объекта. В этом случае необходимо указать имя класса COM.
Например, фрагмент кода:
Таб = ПолучитьCOMОбъект("", "Excel.Application");
создает новый документ Excel. В дальнейшем этот документ может быть программно заполнен и сохранен в файл.
Если первый параметр функции пропущен, то будет произведена попытка получить активный объект указанного типа. Если активного объекта указанного типа в настоящий момент не существует, то будет вызвано исключение. Например, в результате выполнения оператора:
П = ПолучитьCOMОбъект( , "Excel.Application");
Переменная П получит значение типа COMОбъект, соответствующее активному приложению MS Excel, если таковое имелось, или будет вызвано исключение, если активных экземпляров MS Excel не было.
Доступность:
Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение.
Пример:
// Получение объекта COM, соответствующего файлу
// Создание нового экземпляра объекта
Таб = ПолучитьCOMОбъект("", "Excel.Application");
// Получение активного объекта
COMОбъект (COMObject)
Конструкторы:
По имени приложения
Описание:
Создает COM-объект (например, Word, Excel и т.д.). Методы и свойства СОМ-объектов в дальнейшем становятся доступными через данный объект.
Доступность:
Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение.
Значит дело было так. Появилась необходимость подключаться к базам по com соединению, для анализа тамошних объектов метаданных. Проблема оказалась в том, что базы могли работать на разных версиях 1С. Пошел в интернет, искал, читал, но все фигня, в оновном все предлагают держать базы на одной версии, что для меня было невозможным.
Кроме, вот этой статьи. Огромное спасибо автору (Леонид Кириенко) и zakiap
Тут уже интересней, но есть пару минусов
1) 1С должна работать от имени учетки с админскими правами.
2) "Варварское" поведение по отношению dllhost.exe :)
3) Могут возникнуть проблемы при одновременном обращении к базам на разных версиях.
Но, как оказалось, самым для меня полезным, оказалась не сама статья, а один из комментариев к ней.
Если присмотрется, то видно, что у него создано несколько оберток для разных версий. Увидев этот коммент, я тут же обрадовался, думал сейчас все расскажут. Но не тут то было, показать, показал, а рассказать забыл)
Инструкция
1. Идем "Панель управления" - "Администрирование" - "Службы компонентов"
2. В оснастке служб компонентов, "Службы компонентов" - "Компьютеры" - "Мой компьютер" - "Приложения COM+"
3. Создаем новое приложение, правой кнопкой по "Приложения COM+" - "Создать" - "Приложение"
4. Выбираем "Создать новое приложение", называем например "1cv8", тип выбираем "Библиотечное приложение"
должно полчуить так
5. Раскрываем "1cv8", правой кнопкой по "Компоненты" - "Создать" - "Компонент".
6. Выбираем вариант "Установка новых компонентов", находим нашу библиотеку comcntr.dll
Находится она в катлоге BIN установленной платформы, у меня например путь такой
"C:\Program Files (x86)\1cv8\8.3.10.2168\bin\comcntr.dll"
должны получить следующую картину
7. Правой кнопкой по "V83.COMConnector.1" - "Псевдоним. ", меняем наименование с "CopyOf.V83.COMConnector.1" на "V83.COMConnector_8.3.9.2033". Данное действие проделываем для всех нужных версий платформ.
8. Открываем "regedit" через пуск или команду "Выполнить", нажимаем F3 и указываем для поиска строку с наименованием созданой нами обертки, например "V83.COMConnector_8.3.9.2033". Или использум для поиска CLSID созданной обертки.
9. Ищем значение в ветке "HKEY_LOCAL_MACHINE" у меня путь такой HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\\ выглядеть должно так
В ветке "InprocServer32" меняем значение у меня, "C:\Program Files (x86)\1cv8\8.3.10.2168\bin\comcntr.dll" на путь к нужной версии длл, в данном случае "C:\Program Files (x86)\1cv8\8.3.9.2033\bin\comcntr.dll".
Данное дейстие проделываем для всех созданных оберток.
Все готово) Для подключения к конкретной версии базы, в 1С теперь нужно использовать следующую конструкцию
В файлах утилита, которая выполнит все эти действия автоматически. Подходит для тех у кого 1С лежит в каталоге
"C:\Program Files (x86)\1cv8". У кого что то отличается, вот ссылка на GitHub . Запустить утилиту нужно от имени администратора. Надеюсь данный материал будет вам полезен)
Специальные предложения
При регистрации библиотек из разных версий 8.3, в одном СОМ приложении, возможно подключиться только к одной из версий.
(15) Решил проблему, создав компоненты в отдельных приложениях СОМ
(15) Методом проб и ошибок- свойствах приложения-> Активация-> Серверное подключение . Так заводится и создается инстанс без ошибок
Спасибо за статью. Мне она помогла, но если просто сделать как написано, возникали ошибки. Куча комментариев с разными ошибками не дали быстрого решения как именно сделать настройки. Предлагаю слегка скорректированный алгоритм. (*) - измененные шаги. В нем нет последних шагов по работе с реестром. У меня сработало на двух серверах.
Если автор посчитает возможным - можно было бы перенести в шапку.
1. Идем "Панель управления" - "Администрирование" - "Службы компонентов"
2. В оснастке служб компонентов, "Службы компонентов" - "Компьютеры" - "Мой компьютер" - "Приложения COM+"
3. Создаем новое приложение, правой кнопкой по "Приложения COM+" - "Создать" - "Приложение"
4*. Выбираем "Создать новое приложение", называем например "1cv8", тип выбираем "Серверное приложение",
Учетная запись - Текущий пользователь, Пользователь с ролью Owner - поставил администратора компьютера (сервера).
(без этого возможна ошибка -2147024769(0x8007007F): Не найдена указанная процедура)
5*. Нажимаем правой кнопкой по ветке 1cv8 – Свойства – Безопасность:
- Снимаем галку «Принудительная проверка доступа для приложений»
- Ставим галку «Применить политику программных ограничений»
- Уровень ограничений «Неограниченный»
(без этого возможна ошибка -2147024891(0x80070005): Отказано в доступе)
6. Раскрываем "1cv8", правой кнопкой по "Компоненты" - "Создать" - "Компонент".
7. Выбираем вариант "Установка новых компонентов", находим нашу библиотеку comcntr.dll (той версии платформы, к которой надо будет подключаться)
-* Если установка платформы на сервер не требуется, то достаточно скопировать в некую папку на сервере все содержимое папки bin соответствующей платформы и указать comcntr.dll из этой папки
8. Правой кнопкой по "V83.COMConnector.1" - "Псевдоним. ", меняем наименование с "CopyOf.V83.COMConnector.1" на "V83.COMConnector_8.3.9.2033". Данное действие проделываем для всех нужных версий платформ.
Читайте также: