Основи роботи з базами 1С через OLE PDF Печать E-mail

Примітка - більша частина написаного тут тексту із прикладами взята по пам'яті (пари років тому вивчав досить докладно, тому може щось в алгоритмах не працювати - я адже їх не копіював звідкись, а прямо відразу й писав, так що за синтаксичні помилки не пинайте) - на даний момент я активно OLE не користуюся (не через якісь проблеми із самим OLE, а через відсутність потреби в його використанні у сучасний момент).

Основні переваги, завдяки яким OLE активно використається:

  • Для зухвалої бази "по барабані" - який тип викликуваної бази (DBF або SQL)
  • Об'єктами викликуваної бази можна управляти всіма відомими методами роботи з об'єктами в 1С (тобто з довідниками працюють методи Вибратьелементи(), Использоватьдату() і т.п., з документами - Вибратьдокументи() і т.п.), відповідно, можна прямо вирішити - варто відпрацьовувати конкретні об'єкти бази 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.

Запам'ятаєте на майбутнє як незаперечний факт:

  • З місцевої бази у базу OLE (і, відповідно, навпаки) прямо методом присвоєння можна перенести тільки числові значення, дати й рядки обмеженої довжини!!! Т.е. місцева база зрозуміє прекрасно без додаткових алгоритмів перетворення отриманого значення тільки зазначені типи значень. Крім того, під обмеженням рядків мається на увазі проблеми з розумінням у місцевій базі реквізитів об'єктів бази OLE типу "Рядок необмеженої довжини". До цьому ж ще треба додати й періодичні реквізити. Природно, під методом присвоєння маються на увазі й спроби зрівняти об'єкти різних баз в одній умові (наприклад, в алгоритмах "Якщо" або "Поки" і т.п.).
  • Є проблеми при спробі перенести "порожню" дату - OLE може неї конвертувати, наприклад, в 31.12.1899 року й т.п. Тому вам краще заздалегідь з'ясувати ті значення, які можуть з'явиться в місцевій базі при переносі "порожніх" дат, щоб передбачити умови перетворення їх у місцевій базі.
  • 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 у рядку тексту місцевої бази. Так що, завжди їсти можливість поламати голову над цим...

    Алгоритми перетворення об'єктів в "легкотравний вид" між базами

    Ясно, що алгоритми перетворення потрібні не тільки для переносу об'єктів між і базами, але й для такого простого завдання, як спроби зрівняти їх між собою

    И ще раз зверну увагу: ОБ'ЄКТИ ОДНІЄЇ БАЗИ ПРЕКРАСНО РОЗУМІЮТЬ ОДИН ОДНОГО, ПРОБЛЕМИ ВИНИКАЮТЬ ТІЛЬКИ ТОДІ, КОЛИ ВИ ПОЧИНАЄТЕ ЗВ'ЯЗУВАТИ МІЖ СОБОЮ ОБ'ЄКТИ РІЗНИХ БАЗ, тобто команда

    Доколе.Фірма=Спроле.Текущийелемент(); 
    // де Доколе - документ бази OLE, а Спроле - довідник "Фірми" бази OLE

    буде прекрасно працювати без помилок. Не забувайте це, щоб не перемудрувати з алгоритмами!

    Отже, повторююся, що прямо перенести, та й просто зрівняти можна тільки дати (причому не "порожні"), числа й рядки обмеженої довжини. Отже, як же нам зрівняти об'єкти різних баз (не числа, не дати, не рядка), тобто як їх перетворити у цей самий рядок/число/дату

    Егоров Андрій Вікторович
    Mista.Ru

     
    « Пред.   След. »