![]() |
![]() |
![]() |
|
Нужен пример работы с 1С 8.0 на Delphi по COM или OLE | ☑ | ||
---|---|---|---|---|
0
inimeg
27.12.07
✎
18:11
|
Прочитал соответствующий топик v8: V8.COMConnector и Delphi
Все здорово но что это за интерфейс IV81COMConnector? Как мне его подключить? Откуда взять? И еще вопрос. Попробовал реализовать через V8.Application (Automation). Автор пишет что проблема с русскими именами пропала. А у меня както она на месте. Все теже "Метод Справочники не поддерживается объектом автоматизации". Что я делаю не так? Где чего не подключил-включил? Работаю на Delphi2005+1C v8.1 (v8.0 таже проблема) Заранее благодарен за любую полезную информацию на эту тему. А то с 8 всего 3 дня как познакомились в отличии от 7. И отношения никак не наладятся ;) |
|||
1
shachneff
27.12.07
✎
18:51
|
Дай ссылку на тему, где я написал, что проблема решена... Не могу сам найти
|
|||
2
shachneff
27.12.07
✎
18:53
|
(1) Сам с собой поговорю... v8: Нужен пример работы с 1С 8.0 на Delphi по COM (не OLE!)
|
|||
3
shachneff
27.12.07
✎
18:54
|
(2) Использовал Delphi 6, 1C v8.0.18
|
|||
4
inimeg
28.12.07
✎
11:37
|
У меня такое подозрение что в Delphi2005 что-то с OLE изменили. Работают только английские аналоги методов 1C да и то не все а через 1...ж(
|
|||
5
Кураж
28.12.07
✎
11:40
|
(0) Может быть найдешь для себя что-то полезное:
http://doc-prg.narod.ru/index_1cv8.htm |
|||
6
inimeg
28.12.07
✎
11:47
|
Кураж - Спасибо. Это я уже читал. Про Эмуляцию EvalExpr там хорошо написано. Но вот с остальным... Беда в том что я пока вобще не могу так настроить соединение с 1С чтобы мог использовать конструкции языка на русском. ж(
shachneff - А ты не мог бы поделится каркасом приложения? Интересует как ты до интерфейса IV81COMConnector достучался. Может быть у меня в этом проблема? |
|||
7
shachneff
28.12.07
✎
12:15
|
(6) Я тогда решал задачу автоматического запуска обработок... Давно это было, а потом появились регламентные задания и все дельфевые приложения канули в лету... Но если не срочно, то я могу попробовать дома повторить подвиг...
|
|||
8
inimeg
28.12.07
✎
12:27
|
shachneff - буду признателен за помошь. Срок исполнения как всегда вчера, но я пока всеравно ковыряюсь безуспешно, так что буду ждать. Если озарение прийдет раньше отпишусь.
|
|||
9
Hadgehogs
28.12.07
✎
12:37
|
Ну все же написано про COMConnector в (5)
http://doc-prg.narod.ru/art_00001/art_00001.htm Что конкретно не получается? |
|||
10
laview
28.12.07
✎
13:13
|
А может быть кто нибудь скажет, что лучше Delphi или Visual Studio?
1C советует все делать на Visual Studio, а я в институте Delphi изучал. Он мне понятнее. В чем между ними разница с точки зрения создания Web приложений для 1С? |
|||
11
Hadgehogs
28.12.07
✎
13:18
|
ну все, счаст начнется...
|
|||
12
Salvador Limones
28.12.07
✎
13:31
|
(10) Как можно сравнивать Delphi и Visual Studio?
|
|||
13
shachneff
28.12.07
✎
13:34
|
Вот мой код, который был в примере, но поправленный под 8.1.
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, V81_TLB, ComObj; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; V81: IV8COMConnector = nil; MainObject: OleVariant; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin V81 := CreateOLEObject('V81.COMConnector') as IV8COMConnector; MainObject := V81.Connect('Srvr="enterprise";Ref="Trade";usr="Шачнев Алексей";pwd="SHA"'); ShowMessage(MainObject.Метаданные.Справочники.Банки.Комментарий); end; end. Обрати внимание на 2 последних модуля в секции uses. Так же необходимо импортировать в проект модуль V81_TLB (Project - Import Type Library. Встать на "1CV81 COM Connector". Нажать Create Unit. Для того, чтобы это получилось, на компе должна быть установлена 1С 8.1 |
|||
14
laview
28.12.07
✎
13:57
|
А готовые шаблоны (которые вместе с web расширением) v8webApplication и v8webService в Delphi тоже можно использовать?
|
|||
15
inimeg
28.12.07
✎
14:33
|
Hadgehogs- соединится получается. Соединение есть. А вот конструкции типа s1C8_ole.Справочники выдают ошибку. Вот что конкретно не работает.
shachneff- Вот ведь...Project - Import Type Library нету такого пункта в Delphi2005 ж( |
|||
16
inimeg
28.12.07
✎
14:45
|
Так... Новые сведения с полей.
Вобщем как подключить V81_TLB в Delphi2005 разобрался. Новый Com Object Delphi 32 и там в качестве родителя выбираем IV8COMConnector. Теперь беда другая. На этой строке ShowMessage(MainObject.Метаданные.Справочники.Банки.Комментарий); Выдает окно Method 'P P C oPг'PoPSPSC<P ' not supported by automation object. Такое впечатление что русские наименования после компиляции не подходят под кодировку с которой работает 1С. Есть соображения на этот счет? |
|||
17
shachneff
28.12.07
✎
14:51
|
(16) Набей русские строки руками, а не копируй из форума.
|
|||
18
shachneff
28.12.07
✎
14:52
|
(16) Плюс я натравил Дельфю на типовую Управление Торговлей. У тебя таких метаданных может не быть!.
|
|||
19
inimeg
28.12.07
✎
15:02
|
shachneff метаданные точно есть. Типовая Бухгалтерия.
В отладчике пишет Project SDIAPP.exe raised exception class EOleError with message 'Method 'Meтaдaнныe' not supported by automation object'. А вот в рантайме выводит |
|||
20
inimeg
28.12.07
✎
15:04
|
shachneff метаданные точно есть. Типовая Бухгалтерия.
В отладчике пишет Project SDIAPP.exe raised exception class EOleError with message 'Method 'Meтaдaнныe' not supported by automation object'. А вот в рантайме выводит Method 'P P C oPг'PoPSPSC<P ' not supported by automation object. Если меняю Meтaдaнныe на синони Metadata то пишет тоже самое но для Справочники Если их меняю на Catalogs то ругается на Банки и т.д. Нашол в настройках проекта пункт code page. Может с ним поиграться? |
|||
21
shachneff
28.12.07
✎
15:05
|
(19), логично, позднее связывание :-)
Ну поиграйся с преобразованием строки в кодировку UTF-8, а затем эту строку выполни... |
|||
22
shachneff
28.12.07
✎
15:06
|
(20) да... 1С работает с UTF-8
|
|||
23
inimeg
28.12.07
✎
15:09
|
Вроде как 1С работает с кодировкой UTF-8 Я прав? А числовое представление этой кодировки что-то найти не могу. В code page можно только числовое значение ввести.
|
|||
24
inimeg
28.12.07
✎
15:10
|
shachneff ж) Опередил.
Погоди, а как можно строку типа ShowMessage(MainObject.Метаданные.Справочники.Банки.Комментарий); Задать в UTF-8 ? этож посути команда... блин.. что-то я туплю ж( |
|||
25
Балабес
28.12.07
✎
15:11
|
стабильно работает только запуск через командную строку
|
|||
26
Биньковский Виталий
28.12.07
✎
15:13
|
поставь Delphi v7
|
|||
27
inimeg
28.12.07
✎
15:16
|
БиньковскийВиталий- ;) Если бы все было так просто ж) Это не решение.
Балабес - это к чему? |
|||
28
inimeg
28.12.07
✎
16:07
|
Числовое представление нашол 65001. Поменял. Не помогло. Поменял кодировку у pas. Не помогло. Не представляю куда теперь двигаться дальше. Срочно нужна помошь ж)
|
|||
29
shachneff
28.12.07
✎
16:47
|
(28) Специально ради тебя дома скачаю Дельфю 2005 и покажу, как решить твою проблему. Решу виртуально, поэтому стребую виртуальное пиво.
|
|||
30
inimeg
28.12.07
✎
17:04
|
shachneff - не вопрос ж) Я даже реального согласен поставить с доставкой ж)
|
|||
31
Биньковский Виталий
28.12.07
✎
17:12
|
Ситуация у тя сложная, если верно(22), в 2005 текст юникоде. Есть сложный путь, как то делал. Нужно подменить делфевый механизм диспетчеризации типа Variant. у меня в результате было примерно так (коммент из реализации) (не пинайте, писалось хрен знает когда)
{--------------------- Mpc-интерпретация вызовов IDispatch --------------------} { количество параметров - не менее одного имя функции или процедуры (любое, Ini есть Variant - переменная) - неуточненное (см. ниже) имя параметра последний параметр (чаще единственный): при вызове как функции - значение по умолчанию, возвращается если параметр не сохранялся ранее. всегда необходим по крайней мене для опознавания типа искомого значения. Важное замечание: При передаче float - абсолютных значений (пример MayLastRadius := Ini.MayLastRadius(3.14)) количество знаков должно быть более 4 (MayLastRadius := Ini.MayLastRadius(3.14000), иначе будет производиться поиск Currency - значения, при сохранении параметр также будет записан как Currency, и при последуюжем чтении будет ошибка. При этом MayLastRadius := Ini.MayLastRadius(6.28 / 2) будет нормально распознан как поиск Double - значения. Это не относится к параметрам по ссылке: var D: Double; begin D := 1; Ini.MayDoubleValue(D); // корректно, поиск именно Double а не Currency при вызове как процедуры - сохраняемое знаачение. предпоследний параметр: при количестве параметров более двух - уточнение имени параметра, удобен при сохранении в цикле. тип может быть любым, логичен Integer или string. при уточнении ключа (параметров более двух) и отсутствии необходимости уточнения имени параметра передать пустую строку при количестве параметров равным двух - уточнение ключа. можно вызвать FullNameComponent: запись Ini.Height(FullNameComponent(Self), Height); чтение Height := Ini.Height(FullNameComponent(Self), Height); при количестве параметров более двух - все до предпоследнего рассматриваются как уточнение ключа относительно базового (Kernel.MainKey) все приводятся к string, допустима передача к примеру счетчика цикла. последний из них может не заканчиваться '\'. передаваемые параметры могут иметь тип Variant, но тогда должны быть инициализированны(иметь тип), иначе будет сгенерированно исключение. исключение будет сгенерированно также при отсутствии параметров (см. выше) var MayVarArray: Boolean; begin MayVarArray := Ini.MayVarArray[Name + '\', 'Button123\', 0987654321, 555, False]; псевдокод if OpenKey(MaiKey + 'Form1\Button123\0987654321\', False) and Reg.ValueExists('MayVarArray555') then Result := ReadBool('MayVarArray555') else Result := False; это галимотья, пореальней - procedure TForm4.FormCreate(Sender: TObject); begin (шииирина и высота формы) Width := Ini.Width(Name, Width); Height := Ini.Height(Name, Height); ToolButton1.Down := Ini.ToolButton1Down(False); AddingMode := Ini.AddingMode(Ord(emFirst)); actCloseMainWindow.Checked := Ini.CloseMainWindow(False); actShowEditor.Checked := Ini.ShowEditor(False); actShowPropsHost.Checked := Ini.ShowPropsHost(True); actShowTags.Checked := Ini.ShowTags(True); actShowHierarchy.Checked := Ini.ShowHierarchy(True); actShowHiddden.Checked := Ini.ShowHiddden(False); actMultiSelect.Checked := Ini.MultiSelect(False); actShowTags.Checked := Ini.ShowTags(True); for i := 0 to MaxInt do (восстанавливаем состав и ширину столбцов) begin PropID := Ini.Column('LeafTree', i, MaxInt); if PropID = MaxInt then Break; AddSection(PropID, Ini.Width('LeafTree', i, 120)); end; end; procedure TForm4.FormDestroy(Sender: TObject); begin (шииирина и высота формы) Ini.Width(Name, Width); Ini.Height(Name, Height); Ini.ToolButton1Down(ToolButton1.Down); Ini.AddingMode(Ord(AddingMode)); Ini.BrowserCount(pnlBrowsers.DockClientCount); Ini.ShowPropsHost(actShowPropsHost.Checked); Ini.CloseMainWindow(actCloseMainWindow.Checked); Ini.ShowEditor(actShowEditor.Checked); Ini.ShowTags(actShowTags.Checked); Ini.ShowHierarchy(actShowHierarchy.Checked); Ini.ShowHiddden(actShowHiddden.Checked); Ini.MultiSelect(actMultiSelect.Checked); Ini.UseSuiteLink(actUseSuiteLink.Checked); i := 0; if Kernel.Reg.OpenKey(Kernel.MainKey + 'LeafTree', False) then begin (удаляем старый состав и ширину колонок) while Kernel.Reg.DeleteValue('Column' + IntToStr(i)) do begin Kernel.Reg.DeleteValue('Width' + IntToStr(i)); Inc(i); end; Kernel.Reg.CloseKey; end; (сохраняем новый состав и ширину колонок) for i := 0 to HeaderSections.Count - 1 do begin Ini.Column('LeafTree', i, HeaderSections[i].Tag); Ini.Width('LeafTree', i, HeaderSections[i].Width); псевдокод StoreValue(Kernel.MainKey + 'LeafTree' + '\' + 'Width' + IntToStr(i), HeaderSections[i].Width); end; end; } |
|||
32
inimeg
28.12.07
✎
17:44
|
БиньковскийВиталий - преклдоняю колено перед вашей выкладкой, но.... К чему она? Ничего не понятн, ровным счетом ничего. Можно более доступным языком?
|
|||
33
Биньковский Виталий
28.12.07
✎
17:51
|
никто не говорил что реализация тривиална.
когда вы обращаетесь к полям вариантной переменной, делфи вызывает функцию диспетчеризации. в вашем случае - MainObject.Метаданные. при старте её адрес лежит в VarDispProc. я её подменяю при инициализации модуля: SaveVarDispProc := @VarDispProc; VarDispProc := MpcVarDispInvoke; моя реализация MpcVarDispInvoke var SaveVarDispProc: Pointer; {указатель на оригинальную функцию диспетчеризации OLE} procedure MpcVarDispInvoke(Result: PVariant; const Instance: Variant; CallDesc: PCallDesc; Params: Pointer); cdecl; var ArgType: Word; ByRef: Boolean; function VariantFromPtr: Variant; begin case ArgType of varStrArg: if ByRef then Result := PString(Params^)^ else Result := PString(Params)^; varOleStr: if ByRef then Result := PWideString(Params^)^ else Result := PWideString(Params)^; varBoolean: if ByRef then Result := PBool(Params^)^ else Result := PBool(Params)^; varByte, varSmallint, varInteger: if ByRef then Result := PInteger(Params^)^ else Result := PInteger(Params)^; varSingle: if ByRef then Result := PSingle(Params^)^ else Result := PSingle(Params)^; varDouble: if ByRef then Result := PDouble(Params^)^ else Result := PDouble(Params)^; varDate: if ByRef then Result := PDateTime(Params^)^ else Result := PDateTime(Params)^; varCurrency: if ByRef then Result := PCurrency(Params^)^ else Result := PCurrency(Params)^; varVariant: if ByRef then Result := PVariant(Params^)^ else Result := PVariant(Params)^; else raise Exception.CreateFmt('Invalid DataType - %d', [ArgType]); end; end; const atTypeMask = $7F; atByRef = $80; var FLock: TRTLCriticalSection; ArgCount: Integer; NameProp: string; Arg: Variant; Reg: TRegistry; Key: string; i: Integer; Delta: Integer; begin if (@Instance = @Ini) then begin FLock := Kernel.IniLock; EnterCriticalSection(FLock); try ArgCount := CallDesc^.ArgCount; if ArgCount < 1 then raise Exception.Create('Not enough actual parameters'); NameProp := StrPas(@CallDesc^.ArgTypes[ArgCount]); Key := ''; for i := 0 to ArgCount-1 do begin ArgType := CallDesc^.ArgTypes[i] and atTypeMask; ByRef := CallDesc^.ArgTypes[i] and atByRef > 0; Arg := VariantFromPtr; if (ArgType = varVariant) and (Arg = Unassigned) then raise Exception.Create('Variant parameters must be assigned'); if i = ArgCount - 1 then Break; if (ArgCount > 2) and (i = ArgCount-2) then NameProp := NameProp + string(Arg) else Key := Key + string(Arg); Delta := 4; if ByRef then case ArgType of varDouble, varCurrency, varDate: Delta := 8; varVariant: if TVarData(Arg).VType <> varString then Delta := 16; end; Inc(Integer(Params), Delta); end; Key := IncludeTrailingBackslash(Kernel.MainKey + Key); if ArgType = varVariant then ArgType := TVarData(Arg).VType; Reg := Kernel.Reg; if Result <> nil then begin Result^ := Arg; if Reg.OpenKey(Key, False) and Reg.ValueExists(NameProp) then case ArgType of varString, varStrArg, varOleStr: Result^ := Reg.ReadString(NameProp); varBoolean: Result^ := Reg.ReadBool(NameProp); varByte, varSmallint, varInteger: Result^ := Reg.ReadInteger(NameProp); varCurrency: Result^ := Reg.ReadCurrency(NameProp); varSingle, varDouble: Result^ := Reg.ReadFloat(NameProp); varDate: Result^ := Reg.ReadDateTime(NameProp); end; end else begin Reg.OpenKey(Key, True); case ArgType of varString, varStrArg, varOleStr: Reg.WriteString(NameProp, Arg); varBoolean: Reg.WriteBool(NameProp, Arg); varByte, varSmallint, varInteger: Reg.WriteInteger(NameProp, Arg); varCurrency: Reg.WriteCurrency(NameProp, Arg); varSingle, varDouble: Reg.WriteFloat(NameProp, Arg); varDate: Reg.WriteDateTime(NameProp, Arg); end; end; Reg.CloseKey; finally LeaveCriticalSection(FLock); end; end else asm// вызов оригинала mov eax, Params; push eax; mov eax, CallDesc; push eax; mov eax, Instance; push eax; mov eax, Result; push eax; call SaveVarDispProc; end; end; |
|||
34
Биньковский Виталий
28.12.07
✎
17:52
|
моя реализация пишет/читает в реестр, в вашей нужно заменить одну кодировку на другую
|
|||
35
Биньковский Виталий
28.12.07
✎
17:56
|
пройди отладчиком (в assm!) при работе с вариантной переменной, там видно как компилятор подставляет вызов "родной процедуры", изучи её сырцы, куда параметры он сует. из этого видно:
asm// вызов оригинала mov eax, Params; push eax; mov eax, CallDesc; push eax; mov eax, Instance; push eax; mov eax, Result; push eax; call SaveVarDispProc; end; |
|||
36
inimeg
28.12.07
✎
17:57
|
БиньковскийВиталий - спасибо. Попробую вчитаться. Буду иметь в виду этот вариант решения, хотя он мне и кажется сложным. Всеравно спасибо за помошь.
|
|||
37
Биньковский Виталий
28.12.07
✎
18:03
|
и все-же, в чем сложность паралельно с 2005 D7 поставить?
|
|||
38
inimeg
28.12.07
✎
18:08
|
БиньковскийВиталий - теоретически сложности нет. Прийдется конечно вынести весь функционал работы с 1С из приложения написаного на 2005 в службу и направлять команды синхронизации уже ей скажем по TCP протоколу. Просто хотелось без лишних усложнений, но видимо не получится. Сейчас попробую конечно еще все это проверить на 2007 может там прокатит.
|
|||
39
inimeg
07.01.08
✎
18:04
|
Решение найдено. Для того что бы компилятор Delphi корректно компилировал структуры типа ole1Cv8.Метаданные.Справочники , в понятной для 1Сv8.1 кодировке необходимо у файла проекта выставить кодировку UTF8. Тоесть не у проекта а у самого пасника. ж) Как всегда все оказалось проще чем казалось на первый взгляд. Спасибо всем за помошь в поиске решения.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |