| Основи роботи з базами 1С через OLE |
|
|
|
|
Примітка - більша частина написаного тут тексту із прикладами взята по пам'яті (пари років тому вивчав досить докладно, тому може щось в алгоритмах не працювати - я адже їх не копіював звідкись, а прямо відразу й писав, так що за синтаксичні помилки не пинайте) - на даний момент я активно OLE не користуюся (не через якісь проблеми із самим OLE, а через відсутність потреби в його використанні у сучасний момент). Основні переваги, завдяки яким OLE активно використається:
Приклад 1. Приєднання до бази 1С через OLE. Базаоле=Создатьобъект("V77.Application"); // Одержуємо доступ до OLE об'єкта 1СЛокальна версія (на один користувача): V77L.Application Мережна версія: V77.Application Версія SQL: V77S.Application Далі замість терміна "викликувана база" буде написана просто "база OLE", а замість терміна "зухвала база" - "місцева база" Тепер, ми повинні знати кілька параметрів для запуску бази OLE: Каталог бази, ім'я користувача і пароль. Ну, напевно, ще й бажання запустити 1С у монопольному режимі :) Каталогбазиоле = "C:\program files\1cv77\Моябаза\";Пользовательоле = "Адміністратор"; Парольоле = "qwerty"; МонопольнийрежимOLE = " /m"; // для немонопольного запуску указати порожню рядок! Запускбеззаставки = 1; // для появи заставки (наприклад, щоб спостерігати // процес запуску бази OLE візуально) поставте тут "0" Результатподключения = Базаоле.Initialize ( Базаоле.RMTrade , "/d" + Сокрлп(Каталогбазиоле) + " /n" + Сокрлп(Пользовательоле)+ " /p" + Сокрлп(Парольоле) + МонопольнийрежимOLE, ?(Запускбеззаставки = 1,"NO_SPLASH_SHOW","")); Якщо Результатподключения = 0 Тоді Попередження("Не удалося підключиться до зазначеного базі - перевірте вступні!"); Конецесли; Коментар: функції Сокрлп() коштують у прикладі на випадок, якщо користувач захоче зазначені вище змінні зробити у формі діалогу, а проблема при цьому полягає в тому, що в алгоритм програма передасть повне значення реквізиту (тобто допише наприкінці значення те кількість пробілів, який необхідно для одержання повної довжини рядка (зазначена у властивостях реквізиту діалогу)). Приклад 2. Доступ до об'єктів бази OLE. Запам'ятаєте на майбутнє як незаперечний факт: A) Доступ до констант бази OLE: ЗначениеконстантиOLE = Базаоле.Константа.Датазапретаредактирования;Б) Доступ до довідників і документів бази OLE (через функцію "CreateObject"): СпрOLE = Базаоле.CreateObject("Довідник.Фірми"); // "Создатьобъект" в OLE не працює!ДокOLE = Базаоле.CreateObject("Документ.Расходнаянакладная"); Після створення об'єкта довідника або документа до них застосовні всі методи, що стосуються таких об'єктів в 1С: Спроле.Вибратьелементи();Поки Спроле.Получитьелемент()=1 Цикл Повідомити(Спр.Найменування); Конеццикла; Помітьте, що якщо замість "Повідомити(Спр.Найменування)" ви вкажете "Повідомити(Спр.Текущийелемент())", те замість строкового/числового подання цього елемента програма видасть вам у віконці повідомлення "OLE". Саме це я й мав на увазі, коли говорив, що прямо мало що можна перенести. Т.е. не будуть працювати наступні методи (помилки 1С не буде, але й результат роботи буде нульовою). Розглянемо наступний приклад: СпрOLE = Базаоле.CreateObject("Довідник.Фірми"); // це довідник в базі OLEДока = Создатьобъект("Документ.Расходнаянакладная"); // а це документ в місцевої базі Дока.Новий(); // створюємо новий документ в місцевої базі СпрOLE.Найтипокоду(1,0); // спозиционируем в базі OLE // на фірмі з кодом "1". Дока.Фірма = СпрOLE.Текущийелемент(); // такий метод не спрацює, тому що праворуч від "=" коштує // об'єкт не місцевої бази, і місцева база 1С його не розуміє! Однак, спрацює наступний метод: Спр = Создатьобъект("Довідник.Фірми"); // створюємо об'єкт довідника місцевої базиСпр.Найтипонаименованию(Спроле.Найменування,0,0); // Або Спр.найтипокоду(Спроле.Код,0); // тобто Спроле.Код і Спр.найменування // є звичайними числовими/строковими // значеннями, які розуміє місцева база! Дока.Фірма = Спр.Текущийелемент(); // От тепер всі в порядку, тому що з обох сторін методу // коштують об'єкти тільки місцевої бази! Звідси висновок: можливість доступу до об'єктів бази 1С через OLE потрібно, в основному, тільки для певного завдання - одержати доступ до реквізитів певного елемента довідника або документа. Однак, не забуваємо, що об'єкти бази OLE підтримують всі методи роботи з ними, у т.ч. і "Новий()", тобто приведемо приклад протилежний попередній: Доколе = CreateObject("Документ.Расходнаянакладная"); // Створюємо документ в базі OLEДоколе.Новий(); Спр = Создатьобъект("Довідник.Фірми"); // В місцевої базі одержуємо доступ до довідника Спр.Найтипокоду(1,0); // Знаходимо в місцевої базі фірму з кодом 1 (якщо є) Доколе.Фірма = Спр.Текущийелемент(); // такий метод не спрацює Однак, спрацює наступний метод: Спроле = Базаоле.CreateObject("Довідник.Фірми"); // створюємо об'єкт довідника бази OLEСпроле.Найтипонаименованию(Спр.Найменування,0,0); // Або Спроле.найтипокоду(Спр.Код,0); // тобто Спр.Код і Спр.Найменування є звичайними числовими/строковими значеннями, // які розуміє база OLE! Доколе.Фірма = Спроле.Текущийелемент(); // От тепер всі в порядку, тому що з обох сторін // методу коштують об'єкти бази OLE! Доколе.Записати(); // запишемо документ в базі OLE Якщо Доколе.Провести()=0 тоді Повідомити("Не змогли провести документ!"); Конецесли; В) Доступ до регістрів бази OLE (Не складніше довідників і документів): Реголе=БазаOLE.CreateObject("Регістр.Остаткитоваров");Реголе.Вибратьитоги(); Поки Реголе.Получитьитог()=1 Цикл // Не забуваємо, що треба указувати найменування! Повідомити("Залишок для " + Реголе.Товар.Найменування+ " на складі " + Реголе.Склад.Найменування + " дорівнює " + Реголе.Остатоктовара); Конеццикла; Г) Доступ до перерахувань бази OLE (аналогічний константі): ЗначениеперечисленияOLE = Базаоле.Перерахування.Булево.Не знаю; // :)Помітьте, що користі для місцевої бази від змінної "ЗначениеперечисленияOLE" те й ні, адже подібно довіднику й документу перерахування також прямо недоступно для місцевої бази. Мабуть, приклад роботи з ними може бути наступної (як параметр умови): Смотретьтольковозвратипоставщикам = 1; // припустимо, що це - прапорець в формі діалогу,// який ми або установлюємо, або знімаємо Доколе = Базаоле.CreateObject("Документ.Расходнаянакладная"); Доколе.Вибратьдокументи(Начдата,Кондата); // Начдата і Кондата - також реквізити форми // діалогу, але база OLE прекрасно їх розуміє - // адже це же дати! Поки Доколе.Получитьдокумент()=1 Цикл Якщо Смотретьтольковозвратипоставщикам = 1 Тоді Якщо Доколе.Признакнакладной <> Базаоле.Перерахування.Признрасхнакл.Возвратпоставщику Тоді Продовжити; Конецесли; Інакше Якщо Доколе.Признакнакладной = Базаоле.Перерахування.Признрасхнакл.Возвратпоставщику Тоді Продовжити; Конецесли; Конецесли; Повідомити(Доколе.Вид() + " № "+Доколе.Номердок + " від " + Доколе.датадок); Конеццикла; Д) Доступ до рахунків бази OLE: Счтоле=Базаоле.CreateObject("Рахунок");Счтоле.Найтипокоду("10.5"); // знайшли в базі OLE рахунок 10.5 Е) Доступ до Видамсубконто бази OLE (аналогічний перерахуванню): Видсубконтоконтрагентиоле = Базаоле.Видисубконто.Контрагенти;За аналогією з довідниками і документами працює об'єкт "Періодичний", план рахунків працює за аналогією з Видомсубконто, ну й далі в тім же дусі... Окрему главу присвятимо запиту, а зараз... стіп. Ще пункт забув! Ж) Доступ до функцій і процедур глобального модуля бази OLE! Як же я про це забу-те, а? Оскільки при запуску бази автоматично компілюється глобальний модуль, то нам стають доступні функції й процедури глобального модуля (поправлюся - тільки ті, у яких коштує ознака "Експорт"). Плюс до них ще й різні системні функції 1С. А доступні вони нам через функцію 1С OLE - EvalExpr(). Приведемо приклади роботи з базою OLE: Датаактуальностиоле = Базаоле.EvalExpr("Получитьдатута()");// Повертає дату актуальності Имяпользователяоле = Базаоле.EvalExpr("Имяпользователя()"); // повертає рядок // // спробуємо тепер одержати числове значення ПДВ в елемента номенклатури // через функцію глобального модуля Процентндс(Ставкандс) Експорт! Товоле = Базаоле.CreateObject("Довідник.Номенклатура"); Товоле.Вибратьелементи(); // Знайдемо елемент довідника (не група!) Поки Товоле.Получитьелемент()=1 Цикл Якщо Товоле.Етогруппа()=0 Тоді Перервати; Конецесли; Конеццикла; Числовоезначениепроцентандстовараоле = Базаоле.EvalExpr("Процентндс(Перерахування.Значенияндс." + Товоле.Ставкандс.Ідентифікатор()+")"); Насправді, в останньої рядку приклада я исхитрился й забіг небагато вперед. Справа в тому, що як і запит (див. окрему главу), так і EvalExpr() виконуються усередині бази OLE, причому команди передавается їм звичайним рядком, і тому треба довго думати, як передати необхідні посилання на об'єкти бази OLE у рядку тексту місцевої бази. Так що, завжди їсти можливість поламати голову над цим... Алгоритми перетворення об'єктів в "легкотравний вид" між базами Ясно, що алгоритми перетворення потрібні не тільки для переносу об'єктів між і базами, але й для такого простого завдання, як спроби зрівняти їх між собою И ще раз зверну увагу: ОБ'ЄКТИ ОДНІЄЇ БАЗИ ПРЕКРАСНО РОЗУМІЮТЬ ОДИН ОДНОГО, ПРОБЛЕМИ ВИНИКАЮТЬ ТІЛЬКИ ТОДІ, КОЛИ ВИ ПОЧИНАЄТЕ ЗВ'ЯЗУВАТИ МІЖ СОБОЮ ОБ'ЄКТИ РІЗНИХ БАЗ, тобто команда Доколе.Фірма=Спроле.Текущийелемент(); буде прекрасно працювати без помилок. Не забувайте це, щоб не перемудрувати з алгоритмами! Отже, повторююся, що прямо перенести, та й просто зрівняти можна тільки дати (причому не "порожні"), числа й рядки обмеженої довжини. Отже, як же нам зрівняти об'єкти різних баз (не числа, не дати, не рядка), тобто як їх перетворити у цей самий рядок/число/дату Егоров Андрій Вікторович |
| « Пред. | След. » |
|---|


