WWW.LIB.KNIGI-X.RU
БЕСПЛАТНАЯ  ИНТЕРНЕТ  БИБЛИОТЕКА - Электронные материалы
 

«МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ САНКТ-ПЕТЕРБУРГСКИЙ НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ, МЕХАНИКИ И ОПТИКИ А.Н. Филиппов, А.Н. ...»

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

САНКТ-ПЕТЕРБУРГСКИЙ НАЦИОНАЛЬНЫЙ

ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ

ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ, МЕХАНИКИ И ОПТИКИ

А.Н. Филиппов, А.Н. Сисюков

ПРИМЕНЕНИЕ ВИРТУАЛЬНОГО СТРОКОВОГО ПРОСТРАНСТВА

В САПР ТЕХНОЛОГИЧЕСКОЙ ПОДГОТОВКИ ПРОИЗВОДСТВА.

Методические указания к лабораторным работам.

Интеллектуальные подсистемы САПР Разработки САПР Базы данных Описание применения г.Санкт-Петербург УДК 658.512.011.56 А.Н. Филиппов, А.Н. Сисюков. Применение виртуального строкового пространства в САПР технологической подготовки производства/ Методические указания к лабораторным работам// Описание применения. СПб: НИУ ИТМО, 2013 – с.89 Настоящее пособие предназначено для студентов специализации САПР. В пособии изложены методы программирования при разработке САПР с применением символьного представления объектов, как основы проектирования экспертных систем технологического назначения. Материал, изложенный в пособии, поможет студентам при выполнении курсовых и дипломных проектов для целого ряда дисциплин специализации. Пособие может быть полезным для аспирантов и инженеров, изучающих вопросы теории и практики САПР ТПП.

Адресовано студентам высших учебных заведений, обучающихся по направлению подготовки 230100 – Информатика и вычислительная техника, специальность 230100.68.17 - Интегрированные системы в проектировании и производстве (Магистр - инженер).



Рекомендовано к печати Ученым советом факультета ТМиТ 12 ноября 2013 г, протокол № 9 В 2009 году Университет стал победителем много- этапного конкурса, в результате которого определены 12 ведущих университетов России, которым присвоена категория «Национальный исследовательский университет». Министерством образования и науки Российской Федерации была утверждена программа его развития на 2009–2018 годы. В 2011 году Университет получил наименование «Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики»

Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики, 2013 А.Н. Филиппов, А.Н. Сисюков 2013 СОДЕРЖАНИЕ ВВЕДЕНИЕ

ПРАКТИЧЕСКАЯ ЧАСТЬ ВСПТД

БИБЛИОТЕКА ФУНКЦИЙ ДЛЯ РАБОТЫ С ТРИПЛЕКСНЫМИ СТРОКАМИ В ВСПТД

Функции работы с триплексными строками

Функции работы с триплексными строками, представленными как AnsiString

Класс для работы с триплексными строками

Класс для передачи триплексных строк между процессами

ФУНКЦИИ ФОРМИРОВАНИЯ АНКЕТ (ФРЕЙМОВ)

Анкета типа “текст перехода”

Анкета общего типа

Анкета общего типа для индексированных полей

ДИНАМИЧЕСКАЯ БИБЛИОТЕКА СЕЛЕКЦИИ/МОДИФИКАЦИИ ДАННЫХ ВСПТД

МОДУЛЬ ДОСТУПА К СИСТЕМЕ УПРАВЛЕНИЯ ЗАПИСЯМИ BTRIEVE

Структура класса TBtrFile, базовые свойства и методы

Обращение к Btrieve посредством функций

МОДУЛЬ ДОСТУПА К СЛОВАРЮ МЕТАДАННЫХ И ТАБЛИЦАМ ВСПТД

Структура класса доступа к словарю метаданных и таблицам ВСПТД

Совместное использование классов TBtrFile и TVkTable

ФОРМУЛЫ И ПРАВИЛА В ВСПТД

ПРИЛОЖЕНИЕ 1. БИБЛИОТЕКА BTR32.DLL.

ПРИЛОЖЕНИЕ 2. СЛОВАРЬ МЕТАДАННЫХ TEXKOM.VOC.

ПРИЛОЖЕНИЕ 3. ПРИМЕРЫ ФУНКЦИЙ РАБОТЫ С АНКЕТОЙ, СПИСКАМИ НА С++.

ПРИЛОЖЕНИЕ 4. ТАБЛИЦА SUPERANKETA ИЗ БАЗЫ ЗНАНИЙ BZANKETA.SCE

ПРИЛОЖЕНИЕ 5. СХЕМА ВЗАИМОСВЯЗИ МОДУЛЕЙ ВСПТД

Введение Для понимания материала рекомендуется ознакомится с учебным пособием «ВИРТУАЛЬНОЕ СТРОКОВОЕ ПРОСТРАНСТВО ТЕХНОЛОГИЧЕСКИХ ДАННЫХ. Методы представления данных». Применение инструментальных средств рассчитано на среду программирования Borland Developer Studio 2006 (C++ Builder 10). Предполагается, что читатель знаком с данной средой программирования и языком С++. Также читатель должен быть знаком с визуальной библиотекой компонентов VCL (Visual Component Library), в частности с классами AnsiString, TDataSet и т.д. Практическое использование средств ВСПТД требует от читателя навыки работы с проектом в среде BDS 2006, умение использовать в своих проектах динамически подсоединяемые библиотеки (dynamic-link library DLL) и статические библиотеки (LIB), иметь общие представления о базах данных и системах управления базами данных (СУБД).

Определения, соглашения об именах и сокращениях ВСПТД - Виртуальное Строковое Пространство Технологических Данных.

ТС - триплексная строка.

ЛПР – лицо, принимающее решение.

Под триплетом понимается специальная форма описания в символьном представлении по следующей схеме:

"объект - имя характеристики - отношение - значение –“комментарий".

Данные, известные системе в текущий момент, будем называть фактами. Каждый факт представляется в виде триплета Ф=Prefix,Name,Value, где Prefix - префикс, Name - имя параметра, Value - значение параметра. Здесь префикс обеспечивает контекстное понятие параметра, т.е.

указывает на конкретный описываемый объект. Например, если L - имя параметра, указывающее в общепринятых обозначениях длину описываемого объекта, то выражение Z.L будет обозначать длину заготовки, при условии, что Z - это префикс, указывающий на объект "заготовка". Т.е., Z - это множество харатеристик производственного объекта "заготовка", а Z.L - один из элементов множества Z. Третья составляющая факта "значение" всегда представляется в символьной форме.

Еще неизвестные системе факты будем называть целями системы.

Каждая цель представляется в виде соответствующего триплета цели, у которого префикс и имя параметра организованы так, как и в триплете факта, а "значение" может быть представлено следующим способом:

Префикс.имя=заявка;

Представлены программные модули динамических и статических библиотек, предоставляющих ряд универсальных функций, а также классы и методы доступа из прикладных программ, проектируемых в стиле ООП для ОС Windows:

• Статическая библиотека функций для работы с триплексными строками ВСП (STRTRP.LIB)

• Динамическая библиотека доступа к системе управления записям Pervasive Btrieve (BTRINTF.DLL)

• Динамическая библиотека класса доступа к табличным данным (TABLE.BPL)

• Динамическая библиотека селекции/модификации.данных ВСП (LISTFORM.DLL)

• Динамическая библиотека формирования фреймов (Фреймы-переходы) (VSAPROJECT.DLL)

• Динамическая библиотека формирования фреймов-отчетов (AUTOWORD.DLL) Практическая часть ВСПТД Библиотека функций для работы с триплексными строками в ВСПТД Набор функций работы с триплексными строками реализован в виде статической библиотеки.

Библиотека линкуется к проекту, где необходима работа с триплексными строками. В связи с тем, что в библиотеку включены функции как на базе стандартной библиотеки С/С++, так и функции c Borland – классами, в частности с применением AnsiString, использование библиотеки возможно в средах Borland с данными классами (Builder C++, Delphi). В других средах программирования на С++ (MS Visual C++, gnu С++) возможно использование функции с классом эмулятором AnsiString.

Библиотека: strtrp.lib

Функции работы с триплексными строками

char *trpaddstr(char *trpstr, char *pref, char *name, char *value, char *rem, int type);

Функция добавляет триплет в триплексную строку. Если триплет уже был, то заменяет значение. Возвращает обновленную триплексную строку.

Параметры: trpstr - строка триплетов, pref - префикс, name – имя, value – значение триплета, type – тип триплета, rem – примечание.

Пример применения:

char *trpstr = strdup("$L.NM='Элемент обработки';$L.DSZ='45.6';");

// добавить триплет к строке trpaddstr(trpstr, “L”, “LENGTH”, “120”, NULL, 0);

// значение trpstr после добавления триплета L.LENGTH со значением 120 // "$L.NM='Элемент обработки';$L.DSZ='45.6';$L.LENGTH=120;" // здесь работа с триплексной строкой free(trpstr); // освободить память Если type = 1 значение заключается в апострофы, что предполагает строковое значение для триплета. При type = 0 – числовое значение.

char *trpadd(char *trpstr,char *prf,char *name,char *value,int type);





Функция работает как trpaddstr(…), но без параметра rem.

Реализована функция trpaddW, при использовании которой необходимость в контроле размера буфера отпадает. Реализованна функция на базе класса AnsiString.

Пример применения:

char *trpstr = strdup("$L.NM='Элемент обработки';$L.DSZ='45.6';");

// добавить триплет к строке trpaddstr(trpstr, “L”, “LENGTH”, “120”, 1);

// значение trpstr после добавления триплета L.LENGTH со значением 120 // "$L.NM='Элемент обработки';$L.DSZ='45.6';$L.LENGTH=120;" // здесь работа с триплексной строкой // освободить память free(trpstr);

char* trpaddint(char *trpstr, char *pref, char *name, int v);

Функция добавляет триплет c целым значением в триплексную строку. Если триплет уже был, то заменяет значение. Возвращает обновленную триплексную строку.

Параметры: trpstr - строка триплетов, pref - префикс, name – имя, v – значение.

Пример применения:

char *trpstr = strdup("$L.NM='Элемент обработки';$L.DSZ='45.6';");

// добавить триплет к строке trpaddint(trpstr, “L”, “LENGTH”, 120);

// значение trpstr после добавления триплета L.LENGTH со значением 120 // "$L.NM='Элемент обработки';$L.DSZ='45.6';$L.LENGTH=120;" // здесь работа с триплексной строкой // освободить память free(trpstr);

char * trpmergestr(char * trpstr,char * trpstradd);

Функция сливает две триплексных строки. Возвращает результат слияния.

Параметры: trpstr - основная строка триплетов, trpstradd - добавляемая строка триплетов.

Пример применения:

char *trpstr = strdup("$L.DSZ='45.6';$L.NM='Элемент обработки';”);

char *trpstr1 = strdup("$L1.NM='Элемент обработки 2';$L1.DSZ='47.6';");

// объединить строки char * newtrpstr = trpmergestr(trpstr, trpstr1);

// значение newtrpstr после объединения // $L.DSZ='45.6';$L1.DSZ='47.6';$L.NM='Элемент обработки';

$L1.NM='Элемент обработки 2';

// здесь работа с триплексной строкой // освободить память free(trpstr);

free(trpstr1);

free(newtrpstr);

Для корректной работы данной функции необходимо, чтобы первая триплексная строка (ТС) (trpstr) была отсортирована в лексикографическом порядке имен. Стандартные функции всегда создают и обновляют TC в соответствующем порядке. Однако, иногда допускается создание ТС средствами текстового редактора.

char *trpsort(char *trpstr);

Функция сортирует триплексную строку в лексикографическом порядке имен. Возвращает отсортированную триплексную строку. Эту функцию рекомендуется применять в том случае, когда триплексная строка приготовлена нестандартными методами. Например, конфигурационный файл системы, введенный с применением текстового редактора.

Параметры: trpstr - строка триплетовПример применения:

char *trpstr = strdup("$L.NM='Элемент обработки';$L.DSZ='45.6';

$L.AN=7;$A.NM=Токарная;");

// сортировать char * trpsortstr = trpsort(trpstr);

// значение trpsortstr после сортировки // $A.NM=Токарная;$L.AN=7;$L.DSZ='45.6';$L.NM='Элемент обработки';

// здесь работа с триплексной строкой // освободить память free(trpstr);

free(trpsortstr);

int trpdelpref(char * trpstr, char *pref);

Функция удаляет все триплеты с заданным префиксом из триплексной строки.

Параметры: trpstr - строка триплетов, pref - префикс.

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

");

trpdelpref(trpstr, “N”);

// значение trpstr после сортировки // $L.NM='Элемент обработки';$L.DSZ='45.6';

// здесь работа с триплексной строкой // освободить память free(trpstr);

BOOL trpget(char * trpstr, char *pref, char *name, char *value, int *type);

Функция ищет по префиксу объекта pref и имени name в строке trpstr значение триплета и кладет его в текстовую строку value, тип значение в type. Возвращает true, если значение есть, иначе false.

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

"), value[5];

int type;

if (trpget(trpstr, “N”, “D”, value, &type)) { cout “значение триплета N.D = ” value;

cout “\nтип триплета ” type == 1 ? “строка” : “число”;

} else cout “нет триплета в триплексной строке”;

// на консоль выводим :

// значение триплета N.D = 12 // тип триплета число // освободить память free(trpstr);

Примечание. При применении этой функции следует внимательно следить за переменной value. Ответственность за ее ожидаемый размер остается за программистом. Реализована функция trp_GetW, при использовании которой необходимость в контроле размера буфера отпадает. Реализованна функция на базе класса AnsiString.

BOOL trp_Get(char *trpstr, char *pref, char *name, char *value);

Тоже, но без type.

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

"), value[5];

if (trp_Get(trpstr, “N”, “D”, value)) cout “значение триплета N.D = ” value;

else cout “нет триплета в триплексной строке”;

// на консоль выводим :

// значение триплета N.D = 12 // освободить память free(trpstr);

Реализована функция trp_GetW, при использовании которой необходимость в контроле размера буфера отпадает. Реализованна функция на базе класса AnsiString.

char * trpgetname (char *trpstrin);

Функция возвращает имя первого триплета в триплексной строке.

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

");

char * nm = trpgetname(trpstr);

// значение nm: “N.D” // освободить память free(trpstr);

int del_trp(char *trpstr,char *pref,char *namei, int type);

Функция удаляет триплеты с заданным префиксом и именем из триплексной строки.

Параметры: trpstr - строка триплетов, pref - префикс, namei - имя, type - тип.

Реализована функция trpdelW, при использовании которой необходимость в контроле размера буфера отпадает. Реализованна функция на базе класса AnsiString.

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

");

del_trp(trpstr, “L”, “NM”, 1);

// значение trpstr после удаления триплета:

// $N.D=12;$L.DSZ='45.6';

// освободить память free(trpstr);

char *trpgonext(char *trpstr);

Функция переводит указатель на следующий триплет в строке.

Параметры: trpstr - строка триплетов.

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

"), * pointer;

pointer = trpgonext(trpstr);

cout pointer; // $L.NM='Элемент обработки';$L.DSZ='45.6';

pointer = trpgonext(pointer);

cout pointer; // $L.DSZ='45.6';

pointer = trpgonext(pointer);

cout pointer; // NULL // освободить память free(trpstr);

char *trpgoend(char *trpstr);

Функция переводит указатель на конец триплексной строчки.

Параметры: trpstr - строка триплетов.

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

"), * pointer;

pointer = trpgoend(trpstr);

cout pointer; // $L.DSZ='45.6';

// освободить память free(trpstr);

char *trpgoname(char *trpstr);

Функция аналогична trpgetname bool trp_GetFirst(char *trp,char *fullprf, char *value);

Функция возвращает указатель на первый триплет (префикс) и берет его значение.

Параметры: trp - строка триплетов (входной аргумент), fullprf - обозначение триплета (Префикс.Имя) (выходной аргумент), value - значение триплета (выходной аргумент).

Пример применения:

char * trpstr = strdup("$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';

"), * value[5], name[5];

if (trp_GetFirst(trpstr, name, value);

cout “значение триплета ” name “ = ” value;

else cout “строка пуста”;

// на консоль выводим :

// значение триплета N.D = 12 // освободить память free(trpstr);

Функции работы с триплексными строками, представленными как AnsiString

Использование класса AnsiString в системах программирования Borland, а также его эмулятора в других сиcтемах (Microsoft VC++)1, освобождает программиста от применения функций выделения, освобождения памяти.

При получении значений триплетов отпадает необходимость отслеживания переполнения отведенного для них буфера.

для системы VC++ применяется отдельная библиотека импорта с функциями для работы с триплексными строками, собранная под компиляторы Microsoft bool trp_GetW(AnsiString trpstr, AnsiString Triplet, AnsiString &Value);

Функция кладет значение триплета Triplet(Вх.) в ansi-строку Value (Вых.) из строки trpstr (Вх.). Возвращает true, если значение есть, иначе false.

Пример применения:

AnsiString trpstr = "$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';", Value;

if (trp_GetW(trpstr, “L.NM”, Value);

cout “значение триплета L.NM = ” Value.c_str();

else cout “триплета нет в строке”;

// на консоль выводим :

// значение триплета L.NM = Элемент обработки int trpdelW(AnsiString &Record, AnsiString Triplet);

Функция удаляет триплет Triplet из ansi-строки Record. Возвращает не 0, если значение есть, иначе 0.

Параметры: Record – обновляемая триплексная строка (Вых.), Triplet – удаляемый триплет (Вх.)

Пример применения:

AnsiString trpstr = "$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';", Value;

if (trpdelW(trpstr, “L.NM”);

cout “новое значение триплексной строки = ” trpstr.c_str();

else cout “триплета нет в строке”;

// на консоль выводим :

// новое значение триплексной строки = $N.D=12;$L.DSZ='45.6';

int trpaddW(AnsiString &Record, AnsiString Triplet, AnsiString Value);

Функция добавляет триплет в триплексную строку. Если триплет уже был, то заменяет значение.

Возвращает обновленную триплексную строку.

Параметры: Record – обновляемая триплексная строка (Вых.), Triplet – добавляемый триплет (Вх.), Value – значение триплета (Вх.)

Пример применения:

AnsiString trpstr = "$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';";

trpaddW(trpstr, “L.NM”, “Новый элемент обработки”);

сout trpstr.c_str();

// на консоль выводим :

// $N.D=12;$L.NM='Новый элемент обработки';$L.DSZ='45.6';

trpaddW(trpstr, “L.AN”, “23”);

cout trpstr.c_str();

// на консоль выводим :

// $N.D=12;$L.NM='Новый элемент обработки';$L.DSZ='45.6';$L.AN=23;

int trpSetStr(AnsiString &Dst, AnsiString trpstr);

Функция аналогична trpmergestr. Функция сливает две триплексных строки. Возвращает результат слияния.

Параметры: Dst - основная строка триплетов (Вых.), trpstr - добавляемая строка триплетов (Вх.).

Пример применения:

AnsiString trpstr = "$N.D=12;$L.NM='Элемент обработки';$L.DSZ='45.6';", trpstr2 = “$L1.NM='Элемент обработки 2';$L1.DSZ='47.6';";

trpSetStr(trpstr, trpstr2);

сout trpstr.c_str();

// на консоль выводим :

// $N.D=12;$L.NM='Новый элемент обработки';$L.DSZ='45.6';

$L1.NM='Элемент обработки 2';$L1.DSZ='47.6';

Класс для работы с триплексными строками

Класс СVSATripletString создан для работы с триплексной строкой как с объектом (VSA – virtual string area) Класс работает со строками представленными ранее рассмотренным классом AnsiString1.

Применения класса избавляет программиста передавать указатель или ссылку на саму триплексную строку при работе с ней. Данный класс реализует основные методы работы с триплексными строками.

Вместо AnsiString можно использовать более короткое имя класса – String

Интерфейс класса:

–  –  –

Экземпляр класса позволяет обращаться к именованному объекту (триплексной строке) из разных процессов. Внутренняя реализация через механизм виртуальной памяти ОС (на данный момент платформы ОС MS Windows).

class СVSAVirtualMap {

public:

String MapName;

void SetParam(String ParamName, String ParamValue);

String GetParam(String ParamName);

void SetAllParams(String ParamsValue);

String GetAllParams();

СVSAVirtualMap (void);

СVSAVirtualMap (String MapName);

~ CVSAVirtualMap();

private:

СVSATripletString vsaobj;

void SetMap(void);

String GetMap(void);

HANDLE VirtualMap;

struct TMapDump { int size; char *Value; } MapDump;

};

Применение класса в прикладной программе:

Первый процесс (создание объекта если не существует):

СVSAVirtualMap vm(“ProcessExchange”);

vm.SetAllParams(“$E1.NM=’Резец’; $E2.NM=’Сверло’; $E3.NM=’Фреза’;”);

Второй процесс (открытие объекта если существует):

Получаем доступ к триплексной строке, созданной в первом процессе СVSAVirtualMap vm(“ProcessExchange”);

СVSATripletString ts;

ts.vsaString = vm.GetAllParams();

–  –  –

Динамически подсоединяемая библиотека формирования анкет (фреймов) Назначение: процедура предназначена для динамического формирования анкеты при отображении и ввода параметров проектирования на основе их мнемонических имен. Данная процедура может быть вызвана из различных приложений при условии выполнения нижеописанных соглашений.

Библиотека: vsa.dll (vsaproject.dll) Методы организации.

Процедура ( texDialog) имеет вид:

char * texDialog (int texMode, char *forma, char *trpstr, char *config, char *BaseVoc,char *TableName);

texMode - метод формирования анкеты;

- параметры для организации окна анкеты;

forma

- параметры для отображения в анкете;

trpstr config - имя конфигурационного файла;

BaseVoc – имя базы, содержащей словари метаданных;

TableName – имя таблицы локального словаря метаданных. Применяется, когда имя определено не по правилам, иначе NULL.

–  –  –

texMode=0;

Этот вариант предназначен для ввода переменной информации в логико-лингвистические фразы типа “текст перехода”.

В данной ситуации фразы могут иметь, например, такой вид:

"Зенкеровать "$L.KOL " отв., выдерживая размеры " $L.D " " $L.QV "(" $L.WD "|" $L.ND ")" ПС $L.SH $L.OSSH//$Q.ZAGA=”Текст перехода”;$Q.ZAGP=’Переменная информация”;$Q.W=600;$Q.X=100;$Q.Y=200; $Q.H=400;

Первая часть окна анкеты (до символа „) формируется примерно так же, как она выглядит в параметрах, исключая кавычки. Слоты (триплеты) формируются в соответствии с форматом, взятым из словаря. Вторая (переменная) часть анкеты формируется также, как описано в п.2.2.. Заголовок окна формируется из значения параметра $Q.ZAGA.

Заголовок переменной части формируется из параметра $Q.ZAGP. Параметры расположения окна формируются в соответствии с W,X,Y,H. Введены параметры Q.WIDTH, Q.LEFT, Q.TOP, Q.NSTR для совместимости с накопленными базами анкет. Позволяют использовать DOSразмерность независимо от разрешения (перевод условных единиц в пиксели производятся анкетным модулем).

При нормальном завершении работы возвращается триплексная строка в виде:

$P1.NAME1=VALUE1;… $Pn.NAMEn=VALUEn;// текст перехода где $Pi.NAMEi=VALUEi; - триплет i-го поля, включая переменную информацию.

При ненормальном завершении возвращается NULL.

Переходы в базе данных могут быть сформированы таким образом, что пользователю достаточно будет ввести минимум переменной информации.

Например для хранящегося в таблице текста перехода:

"Шлифовать отв-е в разм. " $L.D " " $L.QV "(" $L.WD "|"$L.ND ")" // Согласно тексту перехода, в режиме проектирования пользователю будет достаточно ввести диаметр элемента обработки ($L.D), квалитет на диаметр ($L.QV), верхнее отклонение на диаметр ($L.WD) и нижнее отклонение на диаметр ($L.ND). Для то-го, чтобы данные $L.D и $L.QV были записаны через пробел между ними необходимо ввести: кавычки пробел кавычки ( “ “ ), для ввода в текст перехода после имени с переменной информацией, например, скобочки, надо ввести: “(“. Текст перехода в графе P.TXT можно вводить в несколько строк, он считается законченным, если в конце его написания стоят две наклонные черты.

–  –  –

texMode=1;

Этот вариант предназначен для ввода переменной информации с автоматической генерацией наименований полей.

$$T.FR$T.FP|Падун Б.С.$:T.FU$T.FN$T.LI//$Q.ZAGA=” Фамилии (нижний штамп)”;

$Q.W=600;$Q.X=100;$Q.Y=200;$Q.H=400;

–  –  –

Этот вариант предназначен для ввода переменной информации для индексированных полей.

Пример индексированных триплетов:

$E2.NM=’Резец’; $E2.NM=’Сверло’; $E4.NM=’Фреза’;

В этом случае алгоритм поиска характеристик из словаря сводится к следующим шагам:

1. искать по полному имени, включая цифры.

2. если не нашли по полному имени, то изъять хвостовые цифры из имени и повторить поиск.

Дополнительные условия:

$$T.FR – символ „$ два раза подряд означает недоступность соответствующего поля для редактирования.

$T.FP|Сидоров В.С. – значение по умолчанию, если его нет в строке параметров для отображения.

$:T.FU - символ „: после „$ означает необходимость обязательного заполнения соответствующего поля.

Любое поле может быть снабжено возможностью вызова функции, взятой из параметров конфигурационного файла. Типы функций – отдельная тема.

Динамическая библиотека селекции/модификации данных ВСПТД Динамическая библиотека селекции/модификации данных ВСПТД.

Модуль предназначен для получения данных из таблиц ВСПТД, минуя процесс обращения к другим модулям в прикладной программе.

Библиотека: listform.dll

Организация интерфейса функций:

1. Функция диалога выбора значений таблиц данных или их модификации

–  –  –

Параметры функции:

String BaseBtr – имя файла данных;

String TblCode – имя таблицы для селекции/редактирования;

int TypeBox – тип селекции:

a. Однострочный выбор (TypeBox=0);

b. Многострочный выбор (TypeBox=1);

(В настоящий момент не используется, заменяется параметром Razd);

int ShowCol – номер поля таблицы для отображения (0 – отобразить все поля таблицы) ;

int CodeCol – номер поля для взятия значения (0 – сформировать триплексную строку по выбранной записи таблицы);

char Razd – разделитель значений для многострочного выбора, в случае однострочного выбора Razd = „N;

String MarkerString – строка маркировки схожей строки в таблице диалога;

String Res – результат отработки функции;

2. Функция диалога выбора значений таблиц данных или их модификации с применением модуля работы с таблицами extern "C" __declspec( dllexport ) int LoadDBList(TVkTable *Table, int X,int Y,int W,int H,int Edit,int *key);

Параметры функции:

TVkTable *Table – таблица для отображения в диалоге;

int X,int Y,int W,int H – размерности и положение диалога;

int Edit – флаг редактирования (0 – только чтение);

int *key – возвращаемый код нажатой клавиши.

Модуль доступа к системе управления записями Btrieve Для физического хранения данных на носителях информации выбрана система управление записями (СУЗ) Btrieve фирмы Btrieve Technologies, Inc (NOVELL). Выбор обоснован как спецификой решаемой задачи, так и целью совместимости наработанных алгоритмов связи с ВСПТД в системе DOS-ТЕХКОМ. Btrieve как и многие другие системы имеет ряд недостатков и преимуществ, о которых изложено ниже. Развитие: фирма PERVASIVE СУЗ Btrieve - законченная система управления записями, обеспечивающая необходимыми функциями для хранения, поиска и корректировки данных в файлах баз данных. Благодаря новым методам и структурам СУЗ Btrieve можно игнорировать физическую структуру файлов, поддержку индексов и проблемы параллелизма и сосредоточиться на логических аспектах файлов и баз данных.

Тем не менее, создание баз данных на Btrieve является нетривиальной задачей для SQLпрограммиста.

Для доступа к СУЗ Btrieve включаются вызовы специфической функции в программный код, передавая информацию к СУЗ Btrieve, которая необходима для выполнения требуемой операции. T.к.

соглашения по вызову разные для разных языков высокого уровня и компиляторов, Btrieve имеет интерфейсные подпрограммы для многих наиболее популярных языков и компиляторов, включая следующие:

Microsoft QuiскВАSIС, интерпретатор и компилятор IBM BASIC, Turbo BASIC и несколько других компиляторов BASIC.

Microsoft Pascal или IBM Pascal и несколько других компиляторов Pascal.

Microsoft C, Lattice C, Turbo C, и несколько других компиляторов С Microsoft COBOL, Realia COBOL, MicroFocus COBOL и несколько других компиляторов COBOL.

В данной дипломной работе использован компилятор С++ фирмы Borland версии 5.81 (Borland Builder 10.0) Система имеет как серверную часть, так и клиентскую. Для работы на рабочей станции достаточно располагать только клиентской частью.

Одной из особенностей Btrieve является отсутствие разделения на поля данных. Вместо предлагается использование развитой системы ключей записей. Ключ служит также индексом для быстрого доступа к записи.

Принятие символа blank (пробел) в качестве альтернативного символа конца строки в прикладных программах накладывает ограничения на место хранения баз данных.

Удаление записи приводит к необходимости переиндексации ключей.

Итак, на базе предоставленных Btrieve средств разработано два способа доступа к Btrieve – базам:

1. Обращение через объект класса (ООП) Сам интерфейс класса его методы и свойства реализованы в динамической библиотеке.

Имя библиотеки BtrIntf.dll

2. Обращение посредством функций Данный способ доступа использовался для доступа к Btrieve-данным в системе “ТЕХКОМ” (Dos вариант). И является альтернативой 1му способу. Имя библиотеки btr32.dll B-ДЕРЕВЬЯ ("двоичные деревья") Btrieve хранит все индексы к записям в форме B-деревьев. B-дерево - это структура данных, для которой характерен быстрый доступ и эффективное использование пространства диска. После создания B-дерева, оно не требует периодической поддержки. Отдельное B-дерево создается к каждому ключу, который определяется в файле.

СТРАНИЦЫ ИНДЕКСОВ.

Страницы индексов содержат ключевые значения для доступа к записям данных. Обычно страницы индексов содержат много различных ключевых значений. Каждое ключевое значение на странице имеет адрес записи (или два адреса, когда определяются дублирующие ключи). Btrieve использует эти адреса для поиска записей, содержащих ключевое значение.

ОПЕРАЦИИ УПРАВЛЕНИЯ ЗАПИСЯМИ

Btrieve выполняет 36 отдельных операций, которые можно осуществить из прикладной программы. Для выполнения операций Btrieve прикладная программа должна выполнить следующие задачи:

осуществить все соглашения, необходимые для выполнения операции.

Например, до того как прикладная программа сможет выполнять любой ввод/вывод файла, она должна сделать, прежде всего, файл доступным путем выполнения операции открытия файла инициализировать параметры, требуемые для выполнения специальной операции Btrieve.

Параметры - это переменные или структуры данных программы, которые соответствуют по типу и размеру значениям, которые ожидает Btrieve для данной операции.

выполнить вызов функции Btrieve (BTRV) Точный формат вызова функции Btrieve меняется в зависимости от языка.

оценить результаты вызова функции Btrieve всегда возвращает код статуса, указывающий успех (состояние=0) или неудачу (состояние0) операции. Прикладная программа должна всегда проверять коды ненулевого состояния и принимать соответствующие действия. Кроме того, Btrieve возвращает данные или другую информацию для конкретных параметров в зависимости от операции.

Перечень действий Btrieve и операционные коды, а также краткое описание функции выполняемой операции приведено в приложении A.

КОДЫ СТАТУСА BTRIEVE

Btrieve Record Manager возвращает значение статуса после каждой операции, выполняемой прикладной программой. Значение 0 показывает, что операция выполнилась успешно. Возможные ненулевые коды статуса, возвращаемые Record Manager, описаны в приложении B.

Выход в свет новой версии Btrieve под маркой фирмы Pervasive – Pervasive SQL 2000 позволяет использовать ее как полноценную СУБД. Последний используемый продукт Pervasive SQL 9i

–  –  –

Класс предназначен для работы с файлами Btrieve через Btrieve Microkernel Engine в среде Borland C++ Builder.

Внутренняя структура записи Btrieve файла в ТЕХКОМ базах состоит их трех последовательных ключей:

1. KEY_WORD – непосредственно ключ записи,

2. KEY_NUMBER – ключ номера записи (внутреннее использование)

3. KEY_LENGTH – ключ длины записи (внутреннее использование) Библиотека: btrintf.dll

Интерфейс класса:

class TBtrFile { // приватная секция класса для использования внутри класса

private:

// структуры для внутреннего использования TMemoryStream *FData;

TMemoryStream *FNewData;

// внутренний ключ void* FKeys;

// внутренний буфер ключа AnsiString FRecordKey;

// внутренний буфер данных AnsiString FDataString;

// внутренний буфер имени файла AnsiString FFileName;

// приватный режим открытия файла BTI_SINT FOpenMode;

// модифицируемый ключ записи (KEY_WORD, KEY_NUMBER, KEY_LENGTH) BTI_SINT FKeyNumber;

// размер страницы записи (1024) unsigned short FPageSize;

// приватный размер ключа записи unsigned short FKeySize;

// структура заголовка btrieve-записи TBtrHead FBtrHead;

// приватный признак конца файла bool FEof;

// приватный признак начала файла bool FBof;

// режим состояния записи (приватный) TBtrFileState FState;

// статус выполненной операции (приватный) BTI_SINT FOpState;

// подготовка к работе с файлом (заполнение структур заголовка) bool GetFileInfo(void);

// метод взятия ключа AnsiString GetRecordKey(void);

// метод записи ключа void SetRecordKey(AnsiString NewKey);

// метод взятия длины ключа unsigned short GetRecordKeyLength(void);

// метод записи длины ключа void SetRecordKeyLength(unsigned short ALength);

// метод взятия размеры страницы unsigned short GetPageSize(void);

// метод записи размеры страницы void SetPageSize(unsigned short APageSize);

// метод взятия номера записи unsigned long GetRecordNumber(void);

// метод взятия данных записи AnsiString GetAsString(void);

// метод установки данных записи void SetAsString(AnsiString NS);

// метод взятия длины записи unsigned short GetRecordDataLength(void);

// метод взятия имени файла AnsiString GetFileName(void);

// метод записи имени файла void SetFileName(AnsiString NameString);

// метод взятия режима открытия файла BTI_SINT GetOpenMode(void);

// метод установки режима открытия файла void SetOpenMode(BTI_SINT OM);

// метод взятия значения FKeyNumber BTI_SINT GetKey(void);

// метод установки значения FKeyNumber void SetKey(BTI_SINT KN);

// метод определения состояния файла bool GetActive(void);

// метод открытия/закрытия файла void SetActive(bool NA);

// метод взятия числа записей unsigned long GetRecordCount(void);

// метод взятия режима состояния записи TBtrFileState GetState(void);

// метод взятия состояния операции над файлом BTI_SINT GetOpState(void);

// метод взятия FEof bool GetEof(void);

// метод взятия FBof bool GetBof(void);

// обновить структуры ключей по новому значению bool PrepareKey(AnsiString AKey);

// обновить структуры ключей bool PrepareCurKey(void);

// выполнить внутреннюю операцию Btrieve bool ChangePosition(BTI_WORD OP);

// метод взятия составной записи AnsiString GetAsExtString(void);

// метод установки составной записи void SetAsExtString(AnsiString AS);

// метод взятия признака составной записи int GetIsNoSingleTable(void);

// публичная секция класса для использования в экземплярах класса

public:

// конструктор класса TBtrFile(void);

// деструктор класса ~TBtrFile(void);

// информационная структура версии Btrieve TBtrInfo* GetBtrInfo(void);

// имя btrieve файла, с которым необходимо работать __property AnsiString FileName = {read=GetFileName, write=SetFileName};

// обновить установленное значение ключа (KEY_WORD, KEY_NUMBER, KEY_LENGTH) __property BTI_SINT Key = {read=GetKey, write=SetKey};

// режим открытия файла (приватный, совместный доступ и т.д.) __property BTI_SINT OpenMode = {read=GetOpenMode, write=SetOpenMode};

// индикатор открытия файла __property bool Active = {read=GetActive, write=SetActive};

// режим состояния записи (btrInactive, btrBrowse, btrEdit, btrInsert и т.д.) __property TBtrFileState State = {read=GetState};

// статус выполненной операции (0 - успешно) __property BTI_SINT OpState = {read=GetOpState};

// число записей в файле __property unsigned long RecordCount = {read=GetRecordCount};

// значение ключа текущей записи __property AnsiString RecordKey = {read=GetRecordKey, write=SetRecordKey};

// длина ключа текущей записи __property unsigned short RecordKeyLength = {read=GetRecordKeyLength, write=SetRecordKeyLength};

// номер текущей записи __property unsigned long RecordNumber = {read=GetRecordNumber};

// значение текущей записи __property AnsiString AsString = {read=GetAsString, write=SetAsString};

// значение текущей составной записи __property AnsiString AsExtString = {read=GetAsExtString, write=SetAsExtString};

// взять значение текущей составной записи __property unsigned short RecordDataLength = {read=GetRecordDataLength};

// размер страницы Btrieve-записи (используется только в момент создания файла) __property unsigned short PageSize = {read=GetPageSize, write=SetPageSize};

// признак конца файла __property bool Eof = {read=GetEof};

// признак начала файла __property bool Bof = {read=GetBof};

// признак составной записи (используется вместе с AsExtString) __property int IsNoSingleTable = {read=GetIsNoSingleTable};

// создание файла данных (true - успешно) bool Create(void);

// открытие файла данных (true - успешно) bool Open(void);

// закрытие файла данных (true - успешно) bool Close(void);

// следующая запись файла данных (true - успешно) bool Next(void);

// предыдущая запись файла данных (true - успешно) bool Prev(void);

// первая запись файла данных (true - успешно) bool First(void);

// последняя запись файла данных (true - успешно) bool Last(void);

// найти запись файла данных по ключу(true - успешно) bool Find(AnsiString AKey);

// режим редактирования текущей записи (true - успешно) bool Edit(void);

// режим вставки записи (true - успешно) bool Insert(void);

// подтверждение операции модификации записи (true - успешно) bool Post(void);

// выход из режима модификации записи void Cancel(void);

// удаление текущей записи (true - успешно) bool Delete(void);

// получить запись в буфер данных (true - успешно) bool GetRecordData(void *AData);

// взять запись из буфера данных (true - успешно) bool SetRecordData(void *ANewData, int ALength);

// оператор создания экземпляра класса (из динамической библиотеки) void *operator new(size_t);

// оператор уничтожения экземпляра класса (из динамической библиотеки) void operator delete(void*);

};

Применение класса в прикладной программе:

1. К проекту подключается BtrIntfX.h и линкуется BtrIntfX.lib

2. В исходном модуле описываются необходимые действия (пример создания базы, поиска, чтения, записи, вставки, удаления записи):

// создание экземпляра класса String TpBuffer;

TBtrFile *BF = new TBtrFile;

BF-FileName = “resz_baza.voc”;

–  –  –

Библиотека: btr32.dll См. приложение.

Модуль доступа к словарю метаданных и таблицам ВСПТД Является центральным звеном верхнего уровня. Информация полученная из модуля доступа к системе управления записям Btrieve используется в чистом виде, либо передается в данный модуль посредством одного из свойств интерфейса классса. В последнем случае полученную информационную строчку можно интерпретировать как объект-таблицу.

Здесь и далее небудут приводится определения словаря методанных и таблиц, а рассматриваются вопросы их применения со стороны программиста.

Базовые методы, свойства и события наследуются от класса TСlientDataSet, TDataSet используемый в среде программирования Borland Builder C++ как элемент построения распределнных приложений, и являющийся частью технолгии Borland Midas. Не зависимость от серверов баз данных позволило наиболее полно адаптировать данный компонентный класс для использования в ВСПТД.

Возможности наследования и полиморфизма ООП позволили интерпретировать структуры табличных объектов САПР ТП «ТЕХКОМ» в класс доступа к ним через выбранную систему программирования.

Именно такой подход позволяет использовать большинство встроенных средств работы с БД посредством Builder, включая составление отсчетов, печать и многое другое.

Создание полнофункционального компонента, а не сурогата компонентного класса, и интеграция с модулем доступа к Btrieve еще более упростит задачи программиста в ВСПТД.

Структура класса доступа к словарю метаданных и таблицам ВСПТД Библиотека: table.dll

Интерфейс модуля TVkTable:

сlass TVkTable : public TClientDataSet {

private:

---«-----«------«protected:

public:

//Получить маску по номеру поля AnsiString __fastcall GetMask(int NumField);

//Добавить новое поле с именем FieldName, описанием DisplayName, маской Maska void __fastcall AddField(String FieldName,String DisplayName,String Maska,int Position);

//Удаление поля по имени void __fastcall DeleteField(String FieldName);

//Конструктор 1 __fastcall TVkTable(TComponent* Owner);

//Конструктор 2 __fastcall TVkTable(TComponent* Owner,String NameTable);

virtual __fastcall ~TVkTable();

//Использовать старую маску __property bool UseMask = {read=FUseMask,write=SetUseMask};

//Строка-таблица __property AnsiString AsString = {read=GetAsString, write=SetAsString};

//Тело таблицы __property AnsiString Body = {read=GetBody, write=SetBody};

//Заголовок таблицы __property AnsiString CaptionTable = {read=FCaption,write=FCaption};

//Наименование таблицы в Btr-файле __property AnsiString NameTable = {read=FNameTable,write=FNameTable};

//Строка дополнительных характеристик __property AnsiString AdditionChar = {read=FTblProperties,write=FTblProperties};

__published:

};

Основные св-ва TDataSet & TClientDataSet:

- число полей FieldCount RecordCount - число записей

- номер записи RecNo

Последовательность действий:

1. Создание экземпляра класса TVkTable:

TVkTable *Table = new TVkTable(NULL,"TblSRes");

2. Загрузка таблицы-строки :

String TableString;

---------------Table-AsString = TableString;

3. Работа с таблицей как с TDataSet:

Обращение к полю по номеру:

AnsiString InstrumentName = Table-Fields-Fields[NUM]-AsString;

Обращение к полю по имени:

AnsiString InstrumentName = Table-Fields-FieldByName(“IName”)AsString;

Изменение значения:

Table-Edit(); //- режим редактирования Table-Fields-FieldByName(“IName”)-AsString = InstrumentName;

Table-Post(); //- принять значение

Добавление значения:

Table-Append(); //- режим добавления Table-Fields-FieldByName(“IName”)-AsString = InstrumentName;

Table-Post(); //- принять значение

Удаление Строки:

Table-Delete();

Позиционирование записи:

Table-First(); //- первая запись Table-Next(); //- следующая запись Table-Prior(); //- предыдущая запись Table-Last(); //- последняя запись Table-RecNo = 1; //- переход по номеру

3. Завершение работы:

delete Table;

Совместное использование классов TBtrFile и TVkTable Совместное применение данных классов позволяет использовать табличные объекты ВСПТД, а также другие объекты.

TBtrFile *BF = new TBtrFile;

TVkTable *Table = new TVkTable(NULL,"ReszTable");

BF-FileName = “resz_baza.voc”;

if(BF-Open()) { if(BF-Find(“TableName”)) { Table-AsString = BF-AsString; //Загрузить таблицу

------//----Работа с таблицей----//---BF-Edit();

BF-AsString = Table-AsString; //Сохранить таблицу BF-Post();

} } BF-Close();

delete BF;

delete Table;

Дополнительные примеры использования классов TBtrFile и TvkTable

Функция переноса строки с номером inRow в строку outRow к примеру может быть реализована следующим образом:

int tblMoveRow(TVkTable *Table, int inRow, int outRow) { // контроль на колличество записей в таблице if(inRow Table-RecordCount || outRow Table-RecordCount || outRow == inRow) return(0);

// выделяем память под массив размерностью, равной числу полей String *Str = new String[Table-FieldCount];

// устанавливаем текущую строку в таблице (откуда перенос) Table-RecNo = inRow;

// заполняем массив значениями исходной строки for (int j=0;jTable-FieldCount;j++) Str[j] = Table-Fields-Fields[j]-AsString;

// устанавливаем текущую строку в таблице (куда перенос) Table-RecNo = outRow;

// переходим в режим редактирования Table-Edit();

// заполняем строку таблицы значениями массива for (int j=0;jTable-FieldCount;j++) if(Str[j].Length()) Table-Fields-Fields[j]-AsString = Str[j];

// Принять изменения Table-Post();

// Освободить массив delete [] Str;

return(1);

} В данной функции показан прием работы с классом TVkTable. Рассмотрен вариант реализации копирования содержимого одной строки в другую строку.

В первых строках проверяется выход значений заданных строк за максимальное число строк в таблице, а также на равенство этих строк (outRow == inRow)(копирование строки в нее саму бесмысленно) При выполнении данных условий выполняется возврат нулевого значения.

В следующей строке выделяем память под массив размерностью, равной числу полей и результат присваиваем указателю на объект типа AnsiString, который будет указывать на первый элемент массива.

String *Str = new String[Table-FieldCount];

Следующим шагом идет установка текущей строки в таблице, значения которой будем копировать:

Table-RecNo = inRow;

Далее организуем цикл заполнения массива значениями исходной строки for (int j=0;jTable-FieldCount;j++) Str[j] = Table-Fields-Fields[j]-AsString;

Теперь устанавливаем текущую строку в таблице, куда будем копировать значения.

Table-RecNo = outRow;

Для возможности модификации значений таблицы, необходимо перевести в режим редактирования:

Table-Edit();

Теперь можно заполнять конечную строку таблицы значениями массива for (int j=0;jTable-FieldCount;j++) if(Str[j].Length()) Table-Fields-Fields[j]-AsString = Str[j];

Для подтверждения принятых в строку данных, необходимо выйти из режима редактирования - Table-Post();

Освобождение массива происходит с помощью операции delete delete [] Str;

После чего возвращаем результат успешной отработки.

return(1);

Следующая функция демонстрирует пример взятия значения поля, заданного с помощью индекса FieldNo по номеру строки RecNo String tblgetvalW(TVkTable *menu,int FieldNo,int RecNo) { String Val, me;

int FLen;

if (menu == NULL) return "";

if (RecNomenu-RecordCount) return "";

if (FieldNomenu-FieldCount) return "";

if (menu-RecNo != RecNo) menu-RecNo = RecNo;

Val = menu-Fields-Fields[FieldNo-1]-AsString.TrimRight();

Val = menu-Fields-Fields[FieldNo-1]-AsString;

me = menu-Fields-Fields[FieldNo-1]-EditMask;

FLen = me.Length();

if (menu-Fields-Fields[FieldNo-1]-DataType == ftInteger) Val = AnsiString::StringOfChar('0', FLen-Val.Length()) + Val;

return Val;

} В начале определяем набор вспомогательных переменных.

String Val, me;

int FLen;

Проверяем правильность переданных параметров. В следующей строке идет контроль на нулевой указатель. При отсутсвии данной проверки,в случае передачи нулевого (NULL) указателя мы получим исключение системы о нарушении доступа к памяти по нулевому адресу.

if (menu == NULL) При выполнении контролирующего условия возвращаем константный объект – «пустая строка».

return "";

Далее проводим контроль на выход переданных в функцию параметров за макимальное число число записей и число полей соответсвенно. При выполнении условий выходим из функции.

if (RecNomenu-RecordCount) return "";

if (FieldNomenu-FieldCount) return "";

Проверка индекса текущей строки с индексом необходимой нам строки. И установка индекса при истинности условия.

if (menu-RecNo != RecNo) menu-RecNo = RecNo;

Считываем значения поля установленной стоки таблицы. Поля класса TField, хранимые в объекте Fields класса TFields индексируются с нуля, как обычные массивы посредством общедоступного свойства Fields (типа «массив») класса TFields. Получив доступ к объекту типа TField, обращаемся к его свойству AsString, значением которого и будет содержимое указанного поля.

Val = menu-Fields-Fields[FieldNo-1]-AsString;

Далее обращаемся к свойству EditMask объекта типа TField. Получаем маску редактирования этого поля, для более детального знакомства со свойствами и методами классов обратитесь к литературе по программированию в средах Borland Delphi/Borland Builder/Borland Developer Studio.

me = menu-Fields-Fields[FieldNo-1]-EditMask;

Получаем максимально возможную длину поля FLen = me.Length();

Свойство DataType объекта типа TField определяет тип поля.

В случае целочисленного значения наращиваем полученное число нулями (символ '0') по длине поля с использованием статического метода класса AnsiString StringOfChar:

if (menu-Fields-Fields[FieldNo-1]-DataType == ftInteger) Val = AnsiString::StringOfChar('0', Flen - Val.Length()) + Val;

Как результат возвращаем значение нашего поля.

return Val;

Следующая функция демонстрирует пример записи значения v поля, заданного с помощью индекса FieldNo по номеру строки RecNo таблицы menu void tblplaceW(TVkTable *menu,int FieldNo,int RecNo,String v) { String Val;

int FLen;

if (menu == NULL) return;

if (RecNo menu-RecordCount) return;

if (FieldNo menu-FieldCount) return;

if (menu-RecNo != RecNo) menu-RecNo = RecNo;

menu-Edit();

if (!v.Trim().Length() && menu-Fields-Fields[FieldNo-1]

-DataType != ftString) v = "0";

menu-Fields-Fields[FieldNo-1]-AsString = v.Trim();

menu-Post();

} Аналогично предыдущей функции осуществляем контроль входных параметров.

Переводим таблицу в режим редактирования, вызывая метод Edit() объекта типа TVkTable (TDataSet).

В случае пустого значения и целочисленном типе поля, записываем число 0, используя строковый контейнер. Метод Trim() объекта типа AnsiString обрезает ведущие и конечные пробельные символы.

Обращаясь к методу Post() вводим данные в таблицу.

Пример функции получения имени поля по его номеру col в таблице tbl:

char *tblnamecol(TVkTable *tbl, int col) { return strdup(String(tbl-Fields-Fields[col - 1]

-FieldName).c_str());

} Данная функция возвращает обычный указатель на объект типа char.

Обращаясь к свойству FieldName объекта типа TField мы получаем имя нашего поля, хранимое в виде объекта типа AnsiString. Используя метод char *c_str(void) класса AnsiString, получаем указатель типа char на участок, памяти где хранится имя поля. Дублируем строковый объект на новом участке памяти с помощью функции стандартной библиотеки C и возвращаем результат.

Функция формирования триплексной строки из табличной строки с номером Row. Данная функция позволяет получить триплексную строку именем треплета, в которой служит имя графы таблицы, причем имя поля таблицы должно формироваться в виде “Prefix.Name”.

String makeTrpstrFromTblRow(TVkTable *Table, int Row) { String trpstr, valRow;

int j;

if (Row Table-RecordCount || Row 1) return(trpstr);

for (j = 1; j = Table-FieldCount; j++) { char *nm;

nm = tblnamecol(Table, j);

valRow = tblgetvalW(Table, j, Row);

if (valRow.Length()) trpaddW(trpstr,(String) nm, valRow);

free(nm);

} return(trpstr);

} Здесь организуется цикл прохода по полям таблицы Table. Применяя уже описанные функции tblnamecol, tblgetvalW, trpaddW формируем триплексную строку trpstr.

Функция по действию противоположная предыдущей - переложить значения из триплексной строки trpstr в строку Row таблицы Table.

int makeTblRowFromTrpstr(char *trpstr, TVkTable *Table, int Row) { int i, countCol=0;

char *val;

char *name,*ch;

if(StrLen(trpstr)3 || RowTable-RecordCount)return countCol;

val=(char*)malloc(StrLen(trpstr));

for (i=1;i=Table-FieldCount;i++) { name=tblnamecol(Table, i);

Trim1(name);

ch=strchr(name,'.'); if(ch!=NULL)*ch=0;

if(ch!=NULL && trp_Get(trpstr,name,ch+1,val)) {

–  –  –

tblplaceW(Table, i, Row, val); countCol++;

} if(name!=NULL)free(name);

} if( val!=NULL)free(val);

return(countCol);

} Используя выше описанные функции записываем значения триплетов в соответсвующие их именам поля укзанной строки.

Методика формирования отчетов по данным, хранимым в ВСПТД Общие сведения Названия модуля: autoword.dll Эффективность, простота и удобство работы с текстовыми и табличными данными присуще приложениям семейства MS Office. Приложения Office – универсальные продукты, которые могут использоваться в различных предметных областях.

Программное обеспечение в области технологии приборостроения, наооборот, достаточно специфично и позволяет получать на выходе документы, как правило, пригодные для применения только внутри самой системы и ей подобных из данной области.

Очень привлекательно выглядит возможность использования всей специфики приложения, нацеленного на некоторую предметную область - для получения данных, с простотой и удобством оформления этих данных в приложениях Office.

Мало кто будет спорить с тем фактом, что отчет представленный в приложении MS Word будет более предпочтительным нежели его аналог построенный средствами самого приложения, специфичной предметной области, вчастности технологии приборостроения.

Далее речь идет о представлении данных ВСПТД (см. [1]) в текстовом документе Word. Данные могут быть табличными, числовыми, текстовыми, т.е. все типы данных представленные в ВСПТД. Представленние графических элементов не рассматривается в данной статье, но сама возможность их внедрения в документ имеется и может быть реализована.

Рассматриваемый программный модуль позволяет формировать отчеты на базе табличных данных и триплетов, представленных в ВСПТД. В качестве приложения по формированию отчетов выбран Microsoft Word из пакета Microsoft Office.

В библиотеке представлен базовый набор функций, позволяющий автоматизировать процесс создания документов MS Word на заранее подготовленных шаблонах.

Совместимость: MS Word 2000 и выше.

Что описывается далее в разделе:

1) Объектная модель документа

2) принцип формирования шаблона по принятым в ВСПТД соглашениям

3) программный интерфейс модуля работы с Word и сопряжение с программой на C++ Принцип работы с отчетами.

Таблицы хранимые в ВСПТД могут быть быстро и эффективно подготовлены к печати, с использованием технологии автоматизации MS Word – OLE Automation. Причем детали применения технологии автоматизации упрятаны в самом програмном модуле, а пользователю (программисту) предлагается лишь небольшой набор функций.

Пользователь сам определяет желаемый набор полей таблицы, указывая его в документе Word. Документ сохраняется и в дальнейшем может быть ипользован как шаблон при формировании табличного и нетолько отчета.

В качестве слота, вместо которого в процессе получения отчета, подставляются реальные данные из ВСПТД, используется объект документа Word – «поле».

Хотя в основе лежит объектная модель приложения Office (Word), пользователю не надо вдаваться в подробности ее реализации, а достаточно иметь самые общие представления о работе с полями.

Поле в понятии Word - вычисляемый элемент, который вставлен в документ, поле содержит определенный код и может иметь несколько параметров документа. Обзор типов полей можно получить в диалоговом окне, выбрав в меню Word пункт вставка/поле.

Объект поля в контексте ВСПТД используется для хранения имени триплета. Указанное в поле наименование служит ключом для извлечения данных из ВСПТД и их установки на место слота в документе. После подстановки значения, само поле удаляется. В чем преимущество такого подхода.

Во-первых, увеличивается скорость прохода по тексту, т.к. перебирается массив объектов модели Word, а не весь текст. Во-вторых, если слот остался нетронутым, например нет данных по данному триплету в ВСПТД, он никак не отображается в документе и не выводится на печать.

Абстрактная объектная модель документа Word

Данная схема позволяет увидеть объект поля в составе объектной модели Word. Application – объект самого приложения Word. Document – документ с которым мы работаем. Bookmarks – объект закладок. Selection – объект, определяющий весь набор подъобъектов, попавших в область выделения. Range – собственно текст, который здесь читаем. Fields – объект, определяющий массив полей в составе текущего документа Document. И в самом Fields, в виде его элементов, находятся те самые поля о которых мы говорим.

Объектная модель документа, как и положено любой объектной модели предлагает ряд свойств и методов для каждого объекта. Как было упомянуто программисту, работающему с ВСПТД нет необходимости знакомится с методами и свойствами этих объектов, а достаточно иметь общие представления, как пользователя Word.

Принцип формирования документа-шаблона для отчетов в ВСПТД

Разработаны определенные правила представления слотов в документе, выполняющем роль шаблона при формирования отчета.

Шаблон прежде всего служит для отвязки самих технологических данных от их оформления в конечном документе.

Напомним, что поле в документе Word с настройками по умолчанию не видимо.

Для удобной работы с полями желательно включить отображение полей. Это можно сделать двумя путями: 1) В меню «Сервис/Параметры», на вкладке «Вид» в категории «показывать» устанавливаем галочку «коды полей». При этом принятые настройки глобальны, т.е. при открытии любого документа коды полей будут отображаться. 2) Выделяем тот фрагмент текста, с которым желаем работать и в контекстном меню выбираем «коды/значения полей», после чего будут отображены/спрятаны коды полей. Результат применяется только к текущему документу в данном сеансе работе.

Как добавить новое поле в документ.

В меню вставка/поле выбираем категория «автоматизация», поле DocVariable, в окне ввода «новое имя» вводим имя триплета, например “$Q.NAME”, в результате получим:

–  –  –

Так представляется триплет-слот в документе-шаблоне в составе поля. Любое поле в документе заключено между символами {}.

Приняты следующие соглашения:

1. Имена, начинающиеся со знака «$» соответсвуют одноименному триплету в ВСПТД. Примеры наименований: {$Q.VAL} – будет подставлено значение триплета Q.VAL из ВСПТД.

2. Имена, начинающиеся со знака «#$» соответсвуют имени поля в таблице ВСПТД, для которого делается отчет. В отличии от первого случая, данное поле обязательно располагается в ячейки таблицы. Это связано прежде всего с тем, что подстановка соотвествует значению столбца таблицы в целом, а не конкретному значению. Т.е. в данном случае идет подстановка значений всех строк таблицы, по указанному столбцу. Примеры наименований:

{#$Q.LENGHT} – будет подставлен столбец с именем Q.LENGHT текущей таблицы.

3. Имена, начинающиеся со знака «$$» соответсвуют наименованию графы (т.е.названию столбца). На место данного слота подставляется буквенное обозначение (заголовок) указанной графы. Примеры наименований: {$$Q.D} – будет подставлено название столбца с именем Q.D текущей таблицы, например результатом может быть слово «Диаметр».

4. Возможны специальные управляющие имена, начинающиеся на «$Setup.». Пример: {$Setup.OrientationLandscape} – при наличие такого поля в документе будет применен альбомный тип листа.

Пример шаблона

–  –  –

Программный интерфейс для отчетов в ВСПТД

Для того, чтобы работать с отчетами в среде Word из создаваемого вами приложения необходимо подключить заголовочный файл, который имеется в комплекте инструментария:

–  –  –

Функции, описанные в этом заголовке, которые нас интересуют:

extern "C" __declspec( dllexport ) void * __stdcall StartWord(TVkTable *table, TWordEvents *we);

где, параметр table – указатель непосредственно на саму таблицу отчет для которой делаем;

параметр we – задает доп. свойства формируемого документа, например возможно установить реакцию приложения на некоторое событие (например закрытие документа). В целом праметр может не задаваться.

extern "C" __declspec( dllexport ) void __stdcall EndWord(void *wordObject);

где, параметр wordObject – определяет дескриптор, возвращенный StartWord Подстановочные триплеты хранятся в виде классической триплексной строки и записываются в свойство AdditionChar объекта TVkTable Для понимания дальнейшего примера вы должны ознакомится с вышеизложенным материалом по работе с объектами типа AnsiString и TVkTable. Ниже в примере применяются методы и свойства этих объектов.

Здесь показан пример формирования отчета для таблицы tbl по рассмотренному выше шаблону документа. Полагается, что таблица содержит поля Q.N; Q.NAME; Q.D; Q.LENGTH.

void sendToWordTemplate(TVkTable *tbl) { // Оределяем указатель на объект автоматизации HINSTANCE hFuncAutoWord = 0;

// Создаем доп. переменную TWordEvents We;

// Задаем имя нашего шаблона String str = “example.doc”;

// Присваиваем имя файла шаблона для данной таблицы tbl-PrintTemplate = str;

// Задаем необходимые триплеты tbl-AdditionChar = “$INSTR.NAME=сверло; $CEH.NUMBER=38; $WORKER.NAME= Комаров А.Н.;”;

// Проверяем существует ли данный файл if (!FileExists(tbl-PrintTemplate)) return;

// Запускаем формирование отчета EndWord(hFuncAutoWord, StarWordt(hFuncAutoWord, tbl, &We));

} После отработки программы получится указанный выше результат – таблица, с подставленными значениями столбцов и триплетов.

Рассмотренный пример демонстрирует приемы формирования отчета к таблице ВСПТД и демонстрирует достаточную простоту и удобство в программе на Borland С++.

–  –  –

Типы данных:

ВещЧисло = [“+”|“-”] НатЧисло [“.”[НатЧисло]] [(“e”|”E”) [“+”|“-”]НатЧисло].

НатЧисло = Цифра {Цифра}.

Строка = “„” {ЛатСимвол|КирСимвол|Цифра|Знак} “”.

Цифра = “0”|“1”|“2”|“3”|“4”|“5”|“6”|“7”| “8”|“9”.

ЛатСимвол = “a”|“b”|“c”|“d”|“e”|“f”|“g”|“h”|“i”|“j”|“k”|“l”|“m”|“n”| “o”|“p”|“q”|“r”|“c”|“t”|“u”|“v”|“w”|“x”|“y”|“z”| “A”|“B”|“C”|“D”|“E”|“F”|“G”|“H”|“I”|“J”|“K”|“L”|“M”|“N”| “O”|“P”|“Q”|“R”|“C”|“T”|“U”|“V”|“W”|“X”|“Y”|“Z”.

КирСимвол = “а”|“б”|“в”|“г”|“д”|“е”|“”|“ж”|“з”|“и”|“й”|“к”|“л”|“м”| “н”|“о”|“п”|“р”|“с”|“т”|“у”|“ф”|“х”|“ц”|“ч”|“ш”|“щ”|“Ъ”| “ы”|“ь”|“э”|“ю”|“я”| “А”|“Б”|“В”|“Г”|“Д”|“Е”|“Ё”|“Ж”|“З”|“И”|“Й”|“К”|“Л”|“М”| “Н”|“О”|“П”|“Р”|“С”|“Т”|“У”|“Ф”|“Х”|“Ц”|“Ч”|“Ш”|“Щ”|“Ъ”| “Ы”|“Ь”|“Э”|“Ю”|“Я”.

Кортеж = “{” Элемент {“,” Элемент} “}”.

Элемент = ВещЧисло|Строка|Переменная|Константа| Промежуток|ВероятПараметр.

Промежуток = (“[”|“(”)ВещЧисло “;” ВещЧисло(“[”|“(”).

ВероятПараметр = (ВещЧисло|Строка)“@”[“+”|“-”] НатЧисло.

Пример применения:

Кортежи.

$X.A = {[5; 11), (14; 23.6), 30} – аналогично:

($X.A = 5 И $X.A 11) ИЛИ ($X.A 14 И $X.A 23.6) $X.A = {„Токарный, „Фрезерный, „Сверлильный} – аналогично:

$X.A =„Токарный ИЛИ $X.A=„Фрезерный ИЛИ $X.A=„Сверлильный $X.A = {8@100, 7@70, 2.4@-100} Переменные Переменная = “$” Префикс “.” ИмяПеременной.

Префикс = ЛатСимвол {ЛатСимвол}.

ИмяПеременной = ЛатСимвол {ЛатСимвол|Цифра|“_”}.

Константы Константа = “$” ИмяКонстанты.

ИмяКонстанты = ЛатСимвол {ЛатСимвол|Цифра|“_”}.

Все константы хранятся в файле config.xml Операции

–  –  –

Функции Функция = ИмяФункции“(”Аргумент{ОперПеречисления Аргумент}“)”.

ИмяФункции = ЛатСимвол {ЛатСимвол} Аргумент = ВещЧисло|Строка|Кортеж|Переменная|Константа|Функция.

Функции, реализованные в ДМВ представлены в таблице:

–  –  –

Структура логического правила Правило = “ЕСЛИ” Условие “ТО” Действие {ОперПеречисления Действие}.

Условие = ЛогВыражение{ЛогОпер(ЛогВыражение|“(” Условие “)”)}.

Действие = Переменная ОперПрисвоения Формула.

ЛогВыражение = Формула Отношение Формула.

Формула = Компонент {МатОпер (Элемент|“(” Формула “)”)}.

Компонент = ВещЧисло|Строка|Кортеж|Переменная|Константа|Функция.

Пример применения:

Правило ЕСЛИ ($L.WOB=25 ИЛИ $L.WOB=27) И НЕТ($TT) ТО $E.KTS:='21' Вербальная интерпретация ЕСЛИ вид_обработки рассверлить ИЛИ сверлить И НЕ заданы технические требования ТО сверло общего назначения Функции и классы для работы с ДМВ Общие понятия

1. Вектор декомпозиции формулы (правила) – последовательность лексем, получающаяся в результате грамматического разбора. Для хранения векторов декомпозиции служит следующий пользовательский тип данных: typedef vectorstring SVec, т.е. вектор (класс vector из стандартной библиотеки шаблонов – Standard Template Library, далее просто STL) строк (класс string стандартной библиотеки). Для преобразования строки в вектор декомпозиции используется функция SVec определение которой находиться в заголовочном файле SplitExpression(string Str), CalcEngine.h

Пример применения:

#include “CalcEngine.h” #include iostream.h string formula = “7+8/11-SIN($PI/4)”;

SVec VDec = SplitExpression(formula);

for(unsigned int i = 0; i VDec.size(); i++) cout VDec[i].c_str() “; ” ;

Результат работы программы:

7; +; 8; /; SIN; $PI; /; 4;

Отсутствие открывающей скобки – не ошибка, т.к. приоритеты функции синус (впрочем, как и любой другой функции) и открывающей скобки одинаковы.

2. Контекст задачи – триплексная строка, содержащая факты, с которыми работает дедуктивная машина вывода. Для хранения этой строки служит следующий пользовательский тип данных:

typedef map string, string, less string SSMap, в терминологии STL, шаблон map называется словарм и является, по сути, ассоциативным массивом. Ключ элемента в этом массиве – имя признака, а сам элемент – значение признака. Для преобразования триплексной строки в контекст задачи используется функция SSMap TrpToValue(string TrpStr), для обратного преобразования – string ValueToTrp(SSMap T). Прототипы обеих функций находятся в заголовочном файле CalcEngine.h

Пример применения:

#include “CalcEngine.h” #include iostream.h string TrpStr = “$X.A=6;$X.B=„строка;”;

SSMap TrpMap = TrpToValue(TrpStr);

SSMap::iterator i = TrpMap.begin();

for(i; i!=TrpMap.end();i++) cout “Признак: ” i-first.c_str() “ Значение: ” i-second.c_str();

string TrpStrNew = ValueToTrp(TrpMap);

cout “Триплексная строка:”;

cout TrpStrNew.c_str();

Результат работы программы:

Признак: $X.A Значение: 6 Признак: $X.B Значение: „строка

Триплексная строка:

$X.A=6;$X.B=„строка;

3. Элемент – переменная, которая может принимать значения строкового вещественного и логического типов, а также может представлять кортеж в зависимости от контекста. Для работы с элементами используется класс Elem, описанный в заголовочном файле Elem.h. Описание класса приведено ниже:

class Elem { int Type;

string Var;

double Num;

string Str;

string In;

int Logic;

public:

Elem(int T, string V, double N, string S, string I, int L);

Elem();

Elem(const Elem &E);

const Elem& operator = (const Elem &E);

bool operator (Elem a);

bool operator == (Elem a);

int GType();

string GVar();

double GNum();

string GStr();

string GIn();

int GLogic();

void SVar (string V);

void SNum (double N);

void SStr (string S);

void SInt (string I);

void SLogic(int L);

};

Поле Type служит для хранения типа элемента, может принимать следующие значения:

const int VAR=0 – для переменной, тип которой неизвестен;

const int VAR_REAL=1 – для переменной вещественного типа;

const int VAR_STR=2 – для переменной строкового типа;

const int VAR_INT=3 – для переменной являющейся кортежем;

const int VAR_BOOL=4 – для переменной логического типа;

const int C_REAL=5 – для константы вещественного типа;

const int C_STR=6 – для константы строкового типа;

const int C_INT=7 – для константы являющейся кортежем;

const int C_BOOL=8 – для константы логического типа.

Поле Var служит для хранения символьного имени переменной (например, $X.A). Поля Num, Str, In, Logic служат для хранения значений вещественного, строкового или логического типов или содержимого кортежа. Далее описаны три конструктора: простой, по умолчанию (создает пустой элемент) и конструктор копирования. Также описаны перегруженные операции присвоить (=), меньше () и равно (==) – это необходимо для создания векторов элементов (т.е., в терминологии STL, для помещения объектов типа Elem в контейнер vector). Методы GType(), GVar(), GNum(), GStr(), GIn() необходимы для получения значений соответствующих типов. Методы void SVar(string V), void SNum(double N), void SStr(string S), void SInt(string I), void SLogic(int L) предназначены для быстрого создания элементов (без использования конструктора).

Незначительный перерасход памяти при использовании класса компенсируется удобством работы с ним. Пример работы с классом Elem будет приведен в следующем параграфе.

4. Интервал – в данном контексте, составляющая кортежа. Для работы с интервалами используется класс Inter и пользовательский тип данных typedef vectorInter InterVec, описанный в заголовочном файле Inter.h. Описание класса приведено ниже:

class Inter { int Type;

string Str;

double Num;

double LNum;

double RNum;

char LLim;

char RLim;

float KUv;

public:

Inter(int T, string S, double N, double LN, double RN, char LL, char RL, float KU);

Inter(void);

Inter(const Inter &I);

Inter(int T, string S, double N, float KU);

Inter(int T);

const Inter& operator = (const Inter &I);

bool operator (Inter a);

bool operator== (Inter a);

int GType();

double GNum();

string GStr();

double GLNum();

double GRNum();

char GLLim();

char GRLim();

float GKU();

};

Поле Type определяет тип интервала: 0 – число, 1 – строка, 2 – промежуток. Поля Str и Num служат для хранения строкового или вещественного значений соответственно. Поля LNum служит для хранения левого числа в промежутке, RNum – правого. Поле LLim используются для хранения левого ограничителя в промежутке, RLim – правого. Например, в промежутке (8, -6.78] LNum = 8, RNum = -6.78, LLim = „(, RLim = „]. Напомним, что ограничители „[] означает включение числа в промежуток, ограничитель „() – невключение. Поле KU используется для хранения значения коэффициента уверенности. Далее описаны 5 конструкторов: простой, по умолчанию, копирования, конструктор для создания вероятностных значений и конструктор для создания пустого интервала заданного типа. Перегруженные операции присвоить (=), меньше () и равно (==) описаны для создания векторов элементов типа Inter (пользовательский тип данных InterVec).

Методы int GType(), double GNum(), string GStr(), double GLNum(), double GRNum(), char GLLim(), char GRLim(), float GKU() используются для получения значений соответствующих полей.

Для преобразования строки в кортеж (т.е. вектор интервалов) используется функция InterVec для обратного преобразования StrToInterval(string Str), string IntervalToStr(InterVec IV).

Функции для расчета правил и формул

Для расчета математических, логических и строковых формул используется функция ElemVec CalcFormula(SVec R, SSMap& T = SSMap()), прототип этой функции находится в заголовочном файле CalcEngine.h. Функция порождает исключения типа string. Все параметры данной функции рассмотрены в предыдущем параграфе, так что рассмотрим е работу на конкретных примерах.

Пример применения:

#include iostream.h #include “CalcEngine.h” using namespace std;

void out(string formula);

main() { string f[5] = { “(8-7)-6/2”, “STRCAT(\Hello \, \world\)”, “7/(3+2-5)”, “5 7 ИЛИ 8 11”, };

for(int i = 0; i 5; i++) out(f[i]);

} void out(string formula) { try { ElemVec res = CalcFormula(formula);

switch(res[i].GType()) { case VAR_REAL: cout res[i].GNum endl;

break;

case VAR_STR: cout res[i].GStr().c_str() endl;

break;

case VAR_INT : cout res[i].GIn().c_str() endl;

break;

case VAR_BOOL: cout res[i].GLogic endl;

break;

default: cout “ERROR” endl;

} } catch(string str) { cout str.c_str() endl;

} }

Результат работы программы:

-2 Hello world Ошибка: Деление на ноль.

Данная небольшая программа предназначена для расчета простых математических, логических или строковых формул. Получив строку, содержащую формулу программа рассчитывает е, затем определяет тип получившегося результата и выводит его. В случае возникновения ошибки, выводится соответствующее предупреждение и расчет продолжается.

Можно модифицировать эту программу, заменив массив f запросом пользователю:

...

string f;

cout “Введите формулу”;

cin f;

out(f);

...

Также можно применять функцию CalcEngine с двумя параметрами, т.е. использовать контекст задачи для хранения переменных.

Пример применения:

...

string VSPTD = “$X.A=7;$X.B=4.6;”;

string form = “7+$X.A/($X.B-2)”;

ElemVec res = CalcEngine(SplitExpression(form), TrpToValue(VSPTD));

cout res[0].GNum endl;

string form_1 = “$X.C:=8”;

ElemVec res = CalcEngine(SplitExpression(form_1), TrpToValue(VSPTD));

cout ValueToTrp(VSPTD) endl;

...

Результат работы программы:

9.6923 $X.A=7;$X.B=4.6;$X.C=8;

Из примера видно, что данная форма функции позволяет не только использовать переменные в формулах, но и изменять контекст задачи.

Для расчета правил вывод используется функция bool CalcRule (SVec R, SSMap& T);, прототип этой функции находится в заголовочном файле CalcEngine.h. В случае если правило выполнено, возвращается true, в противном случае – false Функция порождает исключения типа string.

Пример применения:

string VSPTD = “$X.A=5;$X.B=\„строка\”;

string Rule = “ЕСЛИ $X.A3 И $X.B=\„строка\\ ТО $X.C:=$X.A+5/10”;

if(CalcRule(Rule, VSPTD)) cout “Правило выполнено” endl;

else cout “Правило не выполнено” endl;

cout ValueToTrp(VSPTD) endl;

Результат работы программы:

Правило не выполнено $X.A=5;$X.B=„строка;$X.C=1;

Стоит отметить, что функция CalcRule является ключевой функцией Дедуктивной Машины Вывода.

Функции для работы с базами данных

Доступ к базам данных в рассматриваемой системе осуществляется с помощью технологии Microsoft ActiveX Data Objects (ADO). Данная технология представляет собой универсальный механизм доступа к различным источникам данных из приложений баз данных. Основу технологии ADO составляет использование набора интерфейсов общей модели объектов COM, описанных в спецификации OLE DB. Достоинством ADO является то, что базовый набор интерфейсов OLE DB имеется в каждой современной операционной системе Microsoft. Отсюда следует простота обеспечения доступа к данным.

С помощью ADO можно работать со следующими типами баз данных:

dBASE;

Access;

Excel;

Oracle;

Paradox;

MS SQL;

Server;

Sybase;

текстовые файлы;

FoxPro;

Active Directory Service;

Microsoft Jet;

Interbase;

Informix;

PostgreSQL;

MySQL и т.д.

Главное для работы – наличие установленного соответствующего OLE-провайдера («драйвера» соответствующего типа базы данных, который устанавливается в систему, как правило, из дистрибутива этой же базы данных).

Основными функция для работы с базами данных, использующими технологию ADO, являются:

void gSQLout(string FName, string SQL);

TrpTable gSQL(string FName, string SQL, string Prefix);

string gSQL (string FName, string SQL);

Первая из этих функций настраивает работу провайдера баз данных. Предполагается, что к проекту уже подключены следующие компоненты: TADOConnection, TADOQuery и TDataSource (имеющие, к примеру, имена ADOC, ADOQ и DS). При этом в параметре DataSet компонента DS нужно указать соответствующий набор данных, т.е. ADOQ, а в параметре Connection компонента ADOQ – имя соответствующего соединения, т.е. ADOC. Параметр FName функции gSQLout определяет полный путь к файлу базы данных или только имя файла с расширением (при этом предполагается, что все файлы баз данных хранятся в каталоге, определенном параметром Path в файле config.xml). Тип базы данных определяется по расширению, например, файлы с расширением *.mdb являются базами данных Microsoft Access. Параметр SQL определят запрос, передаваемый базе данных. Функция gSQL отличается от gSQLout тем, что не просто настраивает параметры соединения с базой данных, а возвращает конкретное значение (string gSQL(string FName, string SQL)) или кортеж значений в виде массива триплексных строк (TrpTable gSQL(string FName, string SQL,

string Prefix)). Поясним работу данной функций на конкретном примере:

Пример применения:

Пусть существует некоторая база данных db.mdb и в ней таблица table_1. Содержимое данной таблицы представлено ниже:

NUM E_TR1 E_TR2 E_D E_LR E_VI 1 2300-0155 2300-7516 3.00 33.0 35 2 2300-0156 2300-7518 3.10 36.0 40 3 2300-0157 2300-7522 3.15 36.0 40 4 2300-0158 2300-7524 3.20 36.0 40 5 2300-0159 2300-7526 3.30 36.0 40 6 2300-0160 2300-7528 3.35 36.0 40

Тогда для работы с этой таблицей необходимо использовать следующий программный код:

...

string fname = db.mdb;

string sql[4] = {“SELECT E_TR2 FROM table\ WHERE E_D = 3.15”, “SELECT E_D FROM table\ WHERE E_VI 35”, “SELECT E_TR1, E_LR FROM table\ WHERE E_D BETWEEN 3.1 AND 3.3” “SELECT E_TR1, E_LR FROM table\ WHERE E_D = 3.15”};

try { cout gSQL(fname, sql[0]).c_str() endl;

cout gSQL(fname, sql[1]).c_str() endl;

cout gSQL(fname, sql[2]).c_str() endl;

} catch (string str) { cout str.c_str();

} try { TrpVec out = gSQL(fname, sql[3],”E”);

for(unsigned int i = 0; i out.size(); i++) cout TrpToValue(out[i]).c_str() endl;

} catch (string str) { cout str.c_str();

}

Результат работы программы:

2300-7522 {3.10, 3.15, 3.20, 3.30, 3.35} Ошибка: Неверный запрос. Результат содержит больше 1 поля.

$E.TR1=„2300-0155;$E.LR=33.0;

$E.TR1=„2300-0156;$E.LR=36.0;

$E.TR1=„2300-0157; $E.LR=36.0;

Т.е. перегруженная функция gSQL(string FName, string SQL) возвращает одно значение или кортеж, а gSQL(string FName, string SQL, string Prefix) – таблицу в виде массива триплексных строк, при этом параметр Prefix задает префикс элементов в триплексных строках.

Функции для работы с базами знаний

Для работы с базами знаний используются следующие классы:

class Rule;

class Rules.

Класс Rule описывает одно правило (т.е. вне базы знаний). Описание класса представлено ниже:

class Rule { int Type;

SVec If_cond;

SVec Then_cond;

SVec Vars;

string r;

public:

SVec Errors;

SSMap Vsptd;

SSMap New_vsptd;

Rule(string R);

Rule(void);

Rule(const Rule &R);

const Rule& operator = (const Rule &I);

bool operator (Rule a);

bool operator== (Rule a);

int gType(void);

SVec gIf_cond(void);

SVec gThen_cond(void);

SVec gVars(int type = FULL);

string gSRule(void);

void sType(int N);

void sIf_cond(SVec N);

void sThen_cond(SVec N);

};

Поле Type определяет статус правила, 1 – правило выполнено, 0 – не выполнено, -1 – ошибочно, остальные значения зарезервированы для использования в будущем. В поле If_cond хранится антецедент, а в поле Then_cond – консеквент. Для получения значений этих полей служат методы gType, gIf_cond и gThen_cond, а для установки значений полей – sType, sIf_cond и sThen_cond. В поле Vars хранится вектор переменных в антецедент, для получения значения данного поля используется метод gVars, данный метод получает в качестве аргумента целое число, определяющее какие переменные необходимо вернуть (0 – полный набор переменных, 1 – только те переменные, которые нужны для выполнения правила, т.е без тех, что участвуют в функциях ЕСТЬ() и НЕТ()). В поле r хранится текст правила целиком, для получения значения данного поля используется метод gSRule. В поле Errors сохраняются описания ошибок, произошедших во время обработки текущего правила. Поле Vsptd служит для хранения экземпляра контекста задачи (т.е.

сначала, при обработке первого правила, в нем хранятся только переменные, заранее полученные от пользователя либо ничего, затем при обработке последующих правил контекст задачи меняется и сохраняется в этом поле – это позволяет реализовать механизм откатов). В поле New_vsptd хранятся значения рассчитанных системой параметров, т.е. исключая те, что ввел пользователь. Далее описаны три стандартных конструктора: простой, по умолчанию и копирования и три стандартные операции: присвоить (=), меньше () и равно (==).

Для работы с базой знаний используется класс Rules описание класса представлено ниже:

class Rules { vectorRule VecRules;

vectorRule::iterator ci;

bool isSave;

public:

Rules(string FileName);

Rule& operator [] (int p);

bool CalcNext(Rule& R, SSMap SupVsptd, SVec& NextVars);

bool Next (void);

bool Prev (void);

bool Cancel (Rule& R, SVec& NextVars);

Rule Current (void);

bool Comp (void);

void AddR (string R, int i);

void DelR (int i);

void Save (string FileName);

int sz(void);

vectorRule gVecRules();

};

Поле VecRules используется для хранения вектора логических правил, для получения значения поля используется метод gVecRules, для получения количества правил используется метод sz.

Итератор ci указывает на текущее правило, флаг isSave указывает сохранена ли текущая база знаний в файл. Конструктор Rules(string FileName) формирует базу знаний из файла, заданного аргументом FileName. Перегруженная операция индексации возвращает правило с номером, заданным параметром p. Метод CalcNext рассчитывает текущее правило и переводит итератор ci на следующее правило. Метод возвращает true, если правило не последнее в базе и false – в противном случае. Аргумент SupVsptd задает параметры, которые вводит пользователь, т.е. контекст задачи формируется из поля Vsptd предыдущего правила и того, что ввел пользователь. Возвращаемый методом параметр R содержит текущее правило, а параметр NextVars – переменные, которые понадобятся для расчета следующего правила. Метод Next переводит итератор на следующее правило, а Prev – на предыдущее. Метод Cancel отменяет расчет текущего правила, т.е. модифицирует контекст задачи. Возвращаемые значения такие же как в методе CalcNext. Метод Current возвращает текущее правило. Метод Comp проверяет хватает ли переменных для расчета правила. Метод AddR добавляет правило, заданное параметром R после правила с номером, заданным параметром i. Метод DelR удаляет правило, заданное параметром i. Оба метода порождают исключения типа string в случае, если неверен индекс правила.

В качестве иллюстрации работы с базой знаний приведем текст обработчика события нажатия на кнопку «Рассчитать текущее правило» из созданной экспертной системы (в примере также можно увидеть работу со словарем). Все необходимые комментарии расположены прямо в тексте обработчика.

void __fastcall TForm1::NextClick(TObject *Sender) { //Переводим курсор в конец RichEdit1-SelStart = RichEdit1-Text.Length();

RichEdit1-SelStart = RichEdit1-Text.Length();

//То, что ввел пользователь SSMap CurrVsptd;

//Получаем значения из анкеты for(int i = 1; i ValueListEditor1-RowCount; i++) { //имя переменной string nam = VOC-Find(ValueListEditor1-Cells[0][i].c_str())["name"];

//Тип string typ = VOC-Find(ValueListEditor1-Cells[0][i].c_str())["type"];

Значение – пустая строка string val = "";

//строковые значения заключаются в одинарные кавычки if(typ == "real") val = ValueListEditor1-Cells[1][i].Trim().c_str();

else val = "\'"+(string)ValueListEditor1-Cells[1][i].c_str()+"\'";

//избавляемся от пустых строчек if(nam != "" && val != "" && val != "\'\'") CurrVsptd[nam] = val;//добавляем значения в контекст //задачи } //Очищаем запрос необходимых переменных ValueListEditor1-Strings-Clear();

//То, что понадобится на следующем шаге SVec NextVar;

//Если правило не последнее в базе if(R-CalcNext(RU, CurrVsptd, NextVar)) { //Показываем кнопку отмены Prev-Enabled = true;

//Если список переменных, необходимых на след.

//шаге не пуст if(!NextVar.empty()) { //Активизируем анкету ValueListEditor1-Enabled = true;

//И заполняем ее для расчета следующего правила for(unsigned int i = 0; i NextVar.size(); i++) { //Заполняем наименования признаков AnsiString DenomNext = VOC-Find(NextVar[i])["denom"].c_str();

ValueListEditor1-Strings-Add(DenomNext + "=" + "");

//Заполняем маску AnsiString cMask = ChangeMask(const_castchar* (VOC-Find(NextVar[i])["format"].c_str()));

//Если маска не пустая if(cMask != "") { ValueListEditor1-ItemProps[DenomNext]EditMask = cMask;

//Заполняем значения по умолчанию SVec DefVec = VOC-Find(NextVar[i]).gDef();

if(DefVec[0] != "Пусто" && DefVec[0] != "") { ValueListEditor1-ItemProps[DenomNext]-EditStyle = esPickList;

for(unsigned int i = 0; i DefVec.size(); i++) ValueListEditor1-ItemProps[DenomNext]PickList-Add(DefVec[i].c_str());

} else ValueListEditor1-ItemProps[DenomNext]-EditStyle = esSimple;

} } } else ValueListEditor1-Enabled = false;

//Красиво оформляем вывод RichEdit1-Lines-BeginUpdate();

RichEdit2-Lines-BeginUpdate();

try { RichEdit2-Lines-Clear();//Очищаем то, //что найдено AddDesignOut (RichEdit1, RU, VOC);

AddDesignVSPTD(RichEdit2, RU.New_vsptd, VOC);

} __finally { RichEdit1-Lines-EndUpdate();

RichEdit2-Lines-EndUpdate();

} RichEdit1-Lines-Add("");

///////////////////////////////////// //Оформляем запрос к базе данных RadioGroup1-Height = 0;

RadioGroup1-Width = 0;

RadioGroup1-Items-Clear();

//Пребразуем контекст задачи в массив //SQL-запросов DBS = GetDBMap(RU.New_vsptd, VOC);

for(unsigned int i = 0; i DBS.size(); i++) { if(DBS[i]["DB"] != "Пусто" && DBS[i]["SQL_GEN"] != "Пусто") { RadioGroup1-Height += 25;

AnsiString RadioItem = (AnsiString)GetVerbVSPTD(DBS[i], VOC).c_str() + "из БД " + (AnsiString)DBS[i]["DB"].c_str();

if(RadioGroup1-Width (RadioItem.Length())*6.5) RadioGroup1-Width = (RadioItem.Length())*6.5;

RadioGroup1-Items-Add(RadioItem);

} } ///////////////////////////////////// //Работа с базами данных заверщена //Данных достаточно, переходим к следующему //правилу if(!ValueListEditor1-Enabled) Next-Click();

} else//Иначе – заканчиваем расчет { Next-Enabled = false;

ShowMessage("Расчет окончен");

} }

Приложение 1. Библиотека btr32.dll.

Структуры и типы данных.

Управляющая структура открытого файла typedef struct _BTRHEAD { char FCB[128];

fileSpecification file;

keySpecification key,num,length;

int dataStart;

} BTRHEAD;

Заголовок файла BTRIEVE.

typedef struct _fileSpecification { unsigned recordLength;

unsigned pageSize;

unsigned indexCount;

unsigned long stringCount;

unsigned fileFlag;

char reserved[2];

unsigned preAllocate;

} fileSpecification;

Описание ключа.

typedef struct _keySpecification { unsigned position;

unsigned length;

unsigned flag;

unsigned long keyCount;

unsigned char type;

char reserved[5];

} keySpecification;

Управляющая структура сканера.

typedef struct _BTRKEYS { BTRHEAD * owner;

char k[1];

} BTRKEYS;

Режимы открытия файла.

typedef enum _openMode { modeOrdinal = 0, // Обычный режим // Быстрый режим modeQuick =-1, modeReadOnly =-2, // Только для чтения // С верификацией modeVerify =-3, modeExclusive =-4 // Исключительный доступ } openMode;

Описание функций для работы с BTRIEVE.

–  –  –

Функция создает и открывает файл BTRIEVE.

Если указанный файл уже существует, то он удаляется. Возвращает: указатель на управляющую структуру файла BTRIEVE. в случае удачного открытия, NULL - в случае ошибки.

Параметры: fileName - имя файла, keyLen - длина ключа, pageSize - размер страницы в байтах (может быть 512,1024,2048,4096) mode - режим открытия (см. выше).

BTRHEAD * btrOpen(char * fileName,openMode mode);

Функция: открывает существующий файл BTRIEVE.

Возвращает: указатель на управляющую структуру файла BTRIEVE в случае удачного открытия, NULL - в случае ошибки.

Параметры: fileName - имя файла, mode - режим открытия (см. выше).

int btrClose(BTRHEAD * head);

Функция закрывает ранее открытый файл BTRIEVE с освобождением памяти, отведенной под управляющие структуры.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

–  –  –

int btrRead(BTRHEAD * head, char * key, char * data, unsigned long * num) Функция: чтение строки из файла BTRIEVE по ее ключу.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - если строка не найдена.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

key - ключ строки для чтения.

data - буфер для строки.

Номер строки определяется системой и в случае успеха записывается по адресу num. В случае ошибки *num не определено.

int btrReadNum(BTRHEAD * head, char * key, char * data, unsigned long num) Функция: чтение строки из файла BTRIEVE по ее номеру.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - если строка не найдена.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

data - буфер для строки.

num - номер строки для чтения.

Ключ строки определяется системой и в случае успеха записывается по адресу key. В случае ошибки key не определено.

int btrErase(BTRHEAD * head, char * key) Функция: удаление строки из файла BTRIEVE по ее ключу.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - если строка не найдена.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

key - ключ строки для удаления.

int btrEraseNum(BTRHEAD * head, unsigned long num) Функция: удаление строки из файла BTRIEVE по ее номеру.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - если строка не найдена.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

key - номер строки для удаления.

unsigned btrKeyLen(BTRHEAD * head) Функция: определение длины ключа в файле BTRIEVE.

Возвращает: длину ключа, определенную при создании файла.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

unsigned btrStrLen(BTRHEAD * head) Функция: определение максимальной длины строки в файле BTRIEVE.

Возвращает: максимальную длину записи в файле, Параметры: head - указатель на управляющую структуру файла BTRIEVE.

unsigned long btrTotKeys(BTRHEAD * head) Функция: определение количества строк в файле BTRIEVE.

Возвращает: общее количество строк в файле.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

int btrFirst(BTRHEAD * head, char * key) Функция: получение наименьшего ключа строки в файле.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - в файле нет строк.

Параметры: head - указатель на управляющую структуру файла BTRIEVE. Ключ строки определяется системой и в случае успеха записывается по адресу key. В случае ошибки key не определено.

int btrNext(BTRHEAD * head char * key) Функция: получение ключа строки в файле большего чем заданный.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - в файле нет больше строк.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

key - ключ, следующий за которым требуется искать.

Ключ строки определяется системой и в случае успеха записывается по адресу key. В случае ошибки key не определено.

int btrFirstNum(BTRHEAD * head unsigned long *num) Функция: получение наименьшего номера строки в файле.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - в файле нет строк.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

Номер строки определяется системой и в случае успеха записывается по адресу num. В случае ошибки *num не определено.

int btrNextNum(BTRHEAD * head unsigned long *num) Функция: получение номера строки в файле, большего чем заданный.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - в файле нет больше строк.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

num - номер, следующий за которым требуется искать.

Номер строки определяется системой и в случае успеха записывается по адресу num. В случае ошибки *num не определено.

int btrFirstMask(BTRHEAD * head char * key, char * mask) Функция: получение наименьшего ключа строки в файле, соответствующего маске.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - в файле нет строк, соответствующих маске.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

mask - маска для поиска.

Ключ строки определяется системой и в случае успеха записывается по адресу key. Иначе key не определено.

int btrNextMask(BTRHEAD * head char * key, char * mask) Функция: получение ключа строки в файле, соответствующего маске и большего чем заданный.

Возвращает: 0 - в случае успеха, -1 - в случае ошибки, 1 - в файле нет больше строк, соответствующих маске.

Параметры: head - указатель на управляющую структуру файла BTRIEVE.

key - ключ, следующий за которым требуется искать.

mask - маска для поиска.

Ключ строки определяется системой и в случае успеха записывается по адресу key. В случае ошибки key не определено.

const char * const btrWho (void) Функция: возвращает имя последней вызванной функции системы (возможную точку ошибки). Не следует каким-либо образом модифицировать эту строку.

int btrStatus (void) Функция: возвращает код состояния системы.

Код: 0 - нет ошибки -2 - попытка выполнить btrCreate для файла, который уже существует, -1 недостаточно памяти при вызове malloc. 0 - ошибка BTRIEVE (см. описание) int btrCheck(void) Функция: проверка, установлен ли BTRIEVE.

Возвращает:

0 - BTRIEVE не установлен.

-1 - BTRIVE установлен, но версия не допускает использования данных переменной длины.

1 - установлена локальная версия BTRIEVE.

2 - установлена сетевая версия BTRIEVE.

void btrAbort(void) Функция: аварийное освобождение всех ресурсов BTRIEVE, в том числе закрытие всех ранее открытых файлов BTRIEVE.

Приложение 2. Словарь метаданных texkom.voc.

–  –  –

Приложение 3. Примеры функций работы с анкетой, списками на С++.

анкета // подлючить заголовочный файл #include “vsai.h” // содержимое заголовочного файла // extern “C” // { // char* __stdcall texDialog(int texMode, char *forma, char *trpstr, // // char *config, char *, char *);

// void __stdcall texfree(char* trp);

// } void main(void) { // анкета типа текст перехода char *ank = "\" Элемент \" $$:L.OB|Default \" с именем \" $:L.NM \" точить, выдерживая: 1) \" $L.NH \", 2) \" $L.TIM \", 3) \" $L.DSZ \", 4) \" $:L.TW2 \", 5) \" $L.WU \", 6) \" $L.L \" с отношением \" $L.LKD \" между \" $:L.KOL \" элементами.

\"$L.LKD$E.VO//$Q.X=100;$Q.Y=200;$Q.W=520;$Q.H=150;$Q.ZAGA='Пример анкеты типа текст перехода';$Q.ZAGP='Переменная info';";

// триплексная строка char *trp = "$L.NM='Element';$L.DSZ='45.6';";

char * texRes = texDialog (0, ank, trp, NULL, “texkom.voc”, NULL);

// внешний вид диалога анкеты // работа с триплексной строкой texRes //...

// освобождение строки texfree(texRes);

// анкета общего типа char *ank = "$$:L.OB|Default$:L.NM$L.NH$L.TIM$L.DSZ$:L.TW2$L.WU$L.L$L.LKD$:L.KOL//$Q.X=100;$Q.Y=200;$Q.W=520;$Q.H=150;$Q.ZAGA='Пример анкеты общего типа';$Q.ZAGP='Переменная info';";

// триплексная строка char *trp = "$L.NM='Брусок';";

char * texRes = texDialog (0, ank, trp, NULL, “texkom.voc”, NULL);

// работа с триплексной строкой texRes //...

// освобождение строки texfree(texRes);

}

Примеры функций работы с ВСПТД:

// Динамическая загрузка анкеты char *LoadAnk(int type, char *forma, char *trpstr, char *config, char *base, char *tbl) { char *Res = NULL;

char *dllFile = "VsaProject.dll";

char* (__stdcall *texDialog)(int texMode, char *, char *, char *, char *, char *);

void (__stdcall *texfree)(char* trp);

HINSTANCE hAnketa;

// Пытаемся получить идентификатор загруженной библиотеки hAnketa = LoadLibrary(dllFile);

if ((int)hAnketa = HINSTANCE_ERROR) hAnketa = 0;

if (hAnketa) { // Идентификатор загруженной библиотеки был успешно получен texDialog = ( char*(__stdcall*)(int, LPTSTR, LPTSTR, LPTSTR, LPTSTR, LPTSTR)) GetProcAddress(hAnketa, "_texDialog");

texfree = ( void(__stdcall*)(LPTSTR)) GetProcAddress(hAnketa, "_texfree");

if (texDialog && texfree){ //Указатель на функцию texDialog был успешно получен.

char * tr = texDialog (type,forma,trpstr, config,base,tbl);

if(tr ) Res = strdup(tr);

texfree(tr);

} else ShowMessage("Не загрузить функцию из VsaProject.DLL");

}else // Идентификатор загруженной библиотеки не был получен ShowMessage("Не загрузить библиотеку " + String(dllFile));

if (hAnketa!=0) FreeLibrary(hAnketa);

return Res;

} // Динамическая загрузка списка String LoadListTrp(String BaseBtr, String TblCode, int TypeBox, int ShowCol, int CodeCol, char Razd, String MarkerString) { String Res;

char *dllFile = "ListFrm.dll";

int (__stdcall *LoadList)(String, String, int, int, int, char, String, String &);

HINSTANCE hAnketa;

// Пытаемся получить идентификатор загруженной библиотеки hAnketa = LoadLibrary(dllFile);

if ((int)hAnketa = HINSTANCE_ERROR) hAnketa = 0;

if (hAnketa) { // Идентификатор загруженной библиотеки был успешно получен LoadList = ( int(__stdcall*)(String, String, int, int, int, char, String, String&)) GetProcAddress(hAnketa, "_LoadList");

if (LoadList) { // Указатель на функцию был успешно получен.

LoadList (BaseBtr, TblCode, TypeBox, ShowCol, CodeCol, Razd, MarkerString, Res);

} else ShowMessage("Не загрузить функцию из "+String(dllFile));

} else // Идентификатор загруженной библиотеки не был получен ShowMessage("Не загрузить библиотеку " + String(dllFile));

if (hAnketa!=0) FreeLibrary(hAnketa);

return Res;

} // Чтение таблицы из базы bib по ключу key TVkTable *tblreadW(TBtrFile *bib, char *key) { String AS;

if (bib == NULL) return NULL;

if (!bib-Active) return NULL;

if (!bib-Find(key)) return NULL;

if (!(AS=bib-AsExtString).Length()) return NULL;

TVkTable *tbl = new TVkTable(0, key.c_str());

tbl-NameTable = key;

tbl-AsString = AS;

return menu;

} // Чтение таблицы tblName из файла базы с именем file TVkTable *TableReadW(char *file, char *tblName) { TBtrFile *btr = new TBtrFile;

TVkTable *tbl = NULL;

btr-FileName = file;

if(btr-Open()) tbl = tblreadW(btr, tblName);

btr-Close();

delete btr;

return tbl;

} // Взять в виде триплексной строки запись с номером Row таблицы Tbl String GetTrpTable(TVkTable *Tbl, int Row) { String Val, NamF, trpstr;

int Type;

if (Tbl-RecNo != Row) Tbl-RecNo = Row;

for (int i = 0; i Tbl-FieldCount; i++) { Val = Tbl-Fields-Fields[i]-AsString;

NamF = Tbl-Fields-Fields[i]-FieldName;

Type = Tbl-Fields-Fields[i]-DataType==ftString?1:0;

trpstr += "$" + NamF + "=" + (Type ? "'" : "") + Val + (Type ? "'" :

"") + ";";

} Val = String(trpstr);

return Val;

} // Показать анкету по номеру num из базы знаний BZANKETA.SCE String LoadAnketaByNum(int num, String trpStr, String config) { String val;

TVkTable *tbl = TableReadW(“BZANKETA.SCE”, "superanketa");

if (!tbl) return "";

if (tbl-Locate(tbl-Fields-Fields[0]-FieldName, Variant(num), TLocateOptions() loPartialKey)) val = GetTrpTable(tbl, tbl-RecNo);

if (Val.Length()) val = TestTexDialog(1, val, trpStr, config);

return val;

} // генерация анкеты String TestTexDialog(int type, String FullTrp, String Trp, String Config) { char *ank, *del, *clr;

String Res;

char *trp = StrDup(Trp.c_str());

clr = (char*) malloc(FullTrp.Length() + 256);

ank = (char*) malloc(FullTrp.Length() + 256);

del = strdup(FullTrp.c_str());

del[strlen(del)] = 0;

trp_Get(FullTrp.c_str(), "Q", "ANK", ank);

trp_Get(FullTrp.c_str(), "Q", "CLRT", clr);

del_trp(del, "Q", "ANK", 1);

del_trp(del, "Q", "CLRT", 1);

if (!String(ank).Pos("//")) sprintf(ank+strlen(ank), "//%s%s", del, clr);

else sprintf(ank+strlen(ank), "%s%s", del, clr);

char * texRes = LoadAnk(type, ank, trp, Config.c_str(), “texkom.voc”, NULL);

if (texRes) Res = texRes;

free(texRes);

free(ank);

free(del);

free(clr);

free(trp);

return Res;

}

–  –  –

Приложение 5. Программа сканирования виртуального строкового пространства технологических данных (ВСПТД).

Программа выбирает из ВСПТД наименование инструмента (E.NM).

Организуется массив списка инструмента, сортируется методом подсчета.

Результат сортировки выводится в текстовый файл. При этом, если инструмент повторяется, выводится один раз с указанием количества повторений (применяемости).

Ключ в файле ВСПТД имеет вид:

–  –  –

ВСПТД - файл vsp00001.tpp #include stdio.h #include conio.h #include malloc.h #include string.h #include stdlib.h // заголовочные файлы с описанием функций доступа к Btrieve #include btrfun.h #include "btremu.h" #include "trpprg.h" void main() { BTRHEAD * btr;

int n, m, q, i, j, k, numm, l, c[100], p[100];

FILE *fp, *fp1;

unsigned keyLen, strLen;

unsigned long num;

char *key,*data;

char a[100][255], b[100][255], *f, d[100][255];

char filename[14] = "vsp00001.tpp";

btr = btrOpen(filename, modeOrdinal);

keyLen=btrKeyLen(btr);

strLen=btrStrLen(btr);

key=(char *)malloc(keyLen);

data=(char *)malloc(strLen);

n=0;

if (!btrFirst(btr,key)) do { if (!btrRead(btr,key,data,&num)) { trp_Get(data,"E","NM",a[n]);

if ( stricmp (a[n],”“) != 0) n++;

} else printf("Ошибка:(%u) %s ",btrStatus(),btrWho());

} while (!btrNext(btr,key));

btrClose(btr);

// Обнуление массива счетчиков С for (j=0; jn; j++) c[j]=0;

// Создание массива счетчиков С, который содержит индексы // отсортированных элементов массива А for (i=0; i(n-1); i++) for (j=i+1; jn; j++) { if (stricmp(a[i],a[j]) 0) c[j]++;

else c[i]++;

} // Создание отсортированного массива В for (j=0; jn; j++) for (i=0; i255; i++) b[c[j]][i] = a[j][i];

–  –  –

// Печать выходного массива D в файл fp1 = fopen("btr1sort.txt","w");

for (j=0; jk; j++) { fprintf (fp1,"%s",d[j]);

if (p[j]1) fprintf (fp1," Количество повторений - %d", p[j]);

fprintf (fp1,"\n");

} }

Результаты:

Напильник Количество повторений - 3 Развертка Резец Количество повторений - 3 Сверло Количество повторений - 2 Сверло 1,3 Фреза 20 Фреза 30 Центровка 8 Шабер Шлиф. круг Приложение 6. Схема взаимосвязи модулей ВСПТД

–  –  –

Филиппов Александр Николаевич, Сисюков Артем Николаевич Применение виртуального строкового пространства в САПР технологической подготовки производства.

–  –  –

В авторской редакции Редакционно-издательский отдел НИУ ИТМО Зав. РИО Н.Ф. Гусарова Лицензия ИД № 00408 от 05.11.99 Подписано к печати Заказ № Тираж

Похожие работы:

«Научный Совет РАН по физике конденсированных сред Министерство образования и науки РФ Межгосударственный координационный совет по физике прочности и пластичности материалов Физико-технический институт им. А.Ф.Иоффе РАН Нижегородский...»

«Научный журнал КубГАУ, №99(05), 2014 года 1 УДК 621.314 UDC 621.314 ИНВЕРТОРЫ СОЛНЕЧНЫХ ЭЛЕКТРОSOLAR POWER INVERTER WITH IMPROVED СТАНЦИЙ С УЛУЧШЕННЫМИ ТЕХНИЧЕPERFORMANCE СКИМИ ХАРАКТЕРИСТИКАМИ Григораш Олег Владимирович Grigorash Oleg Vladimirovich д.т.н., профессор, заведующий кафед...»

«Рабочая программа дисциплины (модуля) 1. Код и наименование дисциплины (модуля): История и философия науки.2. Уровень высшего образования – подготовка научно-педагогических кадров в аспирантуре.3. Направление подготовки: 01.06.01 МАТЕМАТИКА И МЕХАНИКА 02.06.01 КОМПЬЮ...»

«Приложение к свидетельству М2 Лист о6 утверждении типа средств измерений Всего листов 4'. СОГЛАСОВАНО Виброанализаторы Внесены в Государственный реестр "ТОПАЗ-В" средств измерений Регистрационный М 19302-00 Взамен К Вьшускаются в соответствии с техническими...»

«Петров А.В., Судов Е.В. Программные средства интегрированной логистической поддержки экспортируемой ПВН Интегрированная логистическая поддержка (ИЛП) – это комплекс управленческих, инженерных и информационных технологий [1], направленных на созд...»

«ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ ВОЛГОГРАДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ КАМЫШИНСКИЙ ТЕХНОЛОГИЧЕСКИЙ ИНСТИТУТ (ФИЛИАЛ) ВОЛГОГРАДСКОГО ГОСУДАРСТ...»

«АННОТАЦИИ Рабочие программы дисциплин в структуре Основной образовательной программы по специальности 23.05.01 Наземные транспортнотехнологические средства (специализация № 2 Подъемнотранспортные, строительные, дорожные средства и оборудование) С1.Ф.01 Инос...»

«Информационное сообщение о проведении конкурса на замещение должности директора федерального государственного унитарного эксплуатационного предприятия "Дирекция административного здания Госстандарта России" Федеральное агентство по техническому регулирова...»

«Л.Г.Леготин, А.М.Султанов, С.В. Вячин, И.В. Кузьмин (ОАО НПП ВНИИГИС, ООО НПФ "АМК ГОРИЗОНТ") ОСОБЕННОСТИ ИНКЛИНОМЕТРИЧЕСКИХ ИЗМЕРЕНИЙ В ГОРИЗОНТАЛЬНЫХ СКВАЖИНАХ При строительстве горизонтальных скважин и боковых стволов приходится решать ряд задач по их геофизическому сопровождению...»

«ПРОЕКТНАЯ ДЕКЛАРАЦИЯ ООО "Строительная Компания "Символ" по строительству многоквартирного жилого дома №3 (I этап строительства) в составе комплексной жилой застройки по адресу: Россия,...»

«Министерство образования и науки Российской Федерации Псковский государственный университет В. В. Шевельков, Л. А. Суханов ТЕХНОЛОГИЯ ЛИТЬЯ И СВАРКИ ЧАСТЬ 2. СВАРКА Методические указания по лабораторным работам Рекомендовано к изданию кафедрой "Теория механизмов и машин" Псковского государственн...»

«Инструкция по эксплуатации КОНТРОЛЬНО-КАССОВАЯ МАШИНА МОДЕЛЬ ПОРТ MP-55L-ФKZ ДЛЯ ПУНКТОВ ОБМЕНА ВАЛЮ Т Фирма-производитель: OOД DATECS Ltd Болгария, 1784 София, 115А Цариградско шоссе СОДЕРЖАНИЕ Введение Основные функциональные и техни...»

«Контроллер расширения КР-HART.М2 (аппаратная ревизия 2.0) Руководство по эксплуатации КГПШ.407374.018-01 РЭ 1. Назначение Контроллер расширения КР-HART.М2 (далее контроллер) предназначен для сбора данных с устройств, поддерживающих HART-протокол, и передаче этих данных по MODBUS-протоколу.2. Технические хара...»

«+ СОГЛАСОВАНО Руководитель ГЦИ СИ кий ЦСМ" А. анилов 2008 г. Автоцистерны модели 36133, Внесены в Государственный реестр автотопливозаправщики модели средств измерений Регистрационный Х { 2, Q О^ 36133-011 и ик модификации Взамен Х 12540-03...»

«Министерство образования и науки Российской Федерации Санкт-Петербургский государственный политехнический университет Неделя Науки СПбГПу Материалы научно-практической конференции с международным участием 2–7 декабря 2013 года Инженерно-экономИческИй ИнстИтут часть 1 Санкт-Петербург•2014 УДК 33 ББК 65 Н 42 Неделя науки...»

«Переносный прибор поиска и анализа частичных разрядов при помощи акустического датчика AR200 Руководство по эксплуатации г. Пермь Прибор AR200. Руководство по эксплуатации. Стр. 2 Прибор AR200. Руководство по эксплуатации. Стр. 3 Содержание Описа...»

«Федеральное агентство по образованию Государственное образовательное учреждение высшего профессионального образования Ульяновский государственный технический университет В. К. Манжосов РАСЧЕТНО-ПРОЕКТИРОВОЧНЫЕ И КОНТРОЛЬНЫЕ ЗАДАНИЯ ПО СОПРОТИВЛЕНИЮ МАТЕРИАЛОВ (для студентов ЗВФ) Часть II Методические указания 2-е изда...»

«Развитие системы прогнозирования инвестиционных рисков в телекоммуникационных компаниях (на примере ОАО "МТС") Л.И. Рассолова Рассмотрены возможности развития систем планирования и прогнозирования инвестиционной деятельнос...»

«Министерство образования и науки Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования "НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ ИМ. Р. Е. АЛЕКСЕЕВА" (НГТУ) ПРИНЯТА: УТВЕРЖДАЮ Решение Учебно методического Председатель УМС, университета...»

«Министерство труда, занятости и трудовых ресурсов Новосибирской области Государственное бюджетное профессиональное образовательное учреждение Новосибирской области "Бердский политехнический колледж" (ГБПОУ НСО "Бердский политехнический колледж") УТВЕРЖДАЮ: Зам.директора по УР Т.В.Чуркина ""_20_г Комплект...»

«ПРИБОР ПОЖАРНЫЙ УПРАВЛЕНИЯ Поток–3Н Руководство по эксплуатации АЦДР.425533.003 РЭ СОДЕРЖАНИЕ Список принятых сокращений 1 Общие сведения 2 Технические характеристики 3 Состав изделия 4 Принцип работы прибора 5 Маркировка и пломбирование 6 Упаковка 7 О...»

«ООО "АРСЕНАЛ" 454126 г. Челябинск, ул. Витебская, 4 тел. (351) 267-06-64 тел./факс (351) 260-87-53 http://www.arsenal74.ru E mail: arsenal@arsenal74.ru БЛОК УПРАВЛЕНИЯ КОТЛОМ БУК-МП-06 П Техническое описание и инструкция по эксплуатации АРСО.468361.018 РЭ (V61.26) г. Челябинск 2008 г. СОДЕРЖАНИЕ 1. ТЕХНИЧЕСКОЕ ОПИСА...»

«П УДК 33 Многие начинающие трейдеры думают, что для успешного занятия дэйтрейдингом требуются только три вещи: онлайновый торговый счет, надежный источник котировок в режиме реального времени и верный источник рыночной информации. На самом деле, дэйтрейдинг утомительн...»

«Правительство Москвы Комитет по архитектуре и градостроительству города Москвы ГОСУДАРСТВЕННОЕ УНИТАРНОЕ ПРЕДПРИЯТИЕ "НАУЧНО-ИССЛЕДОВАТЕЛЬСКИЙ И ПРОЕКТНЫЙ ИНСТИТУТ ГЕНЕРАЛЬНОГО ПЛАНА ГОРОДА МОСКВЫ" Гос. контракт № 0173200022712000182 "ПРОЕКТ ПЛАНИРОВКИ УЧАСТКА ЛИНЕЙНОГО ОБЪЕКТА УЛИЧНО-ДОРОЖН...»










 
2017 www.lib.knigi-x.ru - «Бесплатная электронная библиотека - электронные материалы»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.