Данный модуль / библиотека (.dll
) позволит Вам взаимодействовать с базой данных КАБИС напрямую, при помощи функций экспорта, без использования графической обёртки, на которую помимо этого наложено множество ограничений.
На официальном сайте разработчика есть упоминание про API
, но более подробную информацию по этому поводу, кроме пункта с описанием этой возможности, мне найти не удалось :(
Но, так как эта возможность даёт выполнять ряд определённых задач с базой данных библиотеки, Вы и можете наблюдать решение данной проблемы в виде модуля, где имеются все необходимые функции экспорта для манипуляции данными в базе данных.
База данных работает при помощи драйвера ODBC, поэтому решение данной проблемы не заставило себя долго ждать. Так как я не смог открыть файл базы данных при помощи MS Access
и других программ управления базами данных, этот драйвер оставался единственной надеждой.
В будущем планируется доработка модуля и последующее добавление новых функций для более гибкого взаимодействия с базой данных библиотеки. Также, ниже представленные возможности я скоро сделаю бесплатными, а точнее расскажу, как это можно сделать без траты своих средств бесплатно (ничего не буду обещать
).
Посмотреть более подробную документацию можно по этой ссылке (v0.2).
Описать проблемы с работой библиотек можно здесь.
Или можете задать мне свой вопрос в Discord.
P.S: Модуль kapi32u (utils).dll
необходим для выполнения специфических задач, таких как получение пароля от БД из памяти программы
. Возможно это можно сделать каким-то иным путём, но пока я нашёл только это решение данной проблемы.
Перед началом работы, склонируйте данный репозиторий в удобное для Вас место:
git clone https://github.com/kekekekkek/KABIS.API
Скачать репозиторий можно по этой ссылке.
Скачать последнюю версию библиотек можно по этой ссылке.
После того, как все библиотеки и файлы были размещены на Вашем компьютере, Вам необходимо приступить к созданию проекта.
В данном примере будет продемонстрировано то, как правильно нужно настраивать проект для корректной работы библиотек. В данном случае проект будет построен на использовании технологии .NET
(работу функций экспорта на других языках я не тестировал).
- Запустите
Visual Studio
и в появившемся окне выберите пунктСоздание проекта
;
- Далее, в качестве шаблона проекта Вы можете выбрать
Консольное приложение (.NET Framework)
и нажать на кнопкуДалее
;
- В следующем окне Вам необходимо будет дать имя проекту и выбрать платформу
.NET
, после чего, нажать на кнопкуСоздать
. Рекомендуется выбирать платформу не ниже версии4.7
;
- В окне редактора кода, прежде чем начинать работу с библиотеками, первое что Вам потребуется сделать - это настроить проект. В
обозревателе решений
Вам необходимо будет нажатьправой кнопкой мыши
по названию проекта и в контекстном меню выбрать пунктСвойства
;
- В окне настроек необходимо будет выбрать вкладку
Сборка
и внутри неё указатьцелевую платформу
и в качестве значения выбратьx86
, так как драйвер базы данных и сами библиотеки являются32-х
разрядными. Также, Вы можете оставить все настройки по умолчанию, с включённой галочкойПредпочтительна 32-разрядная версия
;
- Далее, в редакторе кода Вам нужно будет скомпилировать проект, нажав на кнопку
▶ Пуск
(запуск с отладкой) или кнопку▷
(запуск без отладки) вверху программы, чтобыIDE
создала файлы сборки в корневном каталоге исходного кода программы (также Вы можете воспользоваться горячими клавишами:Ctrl + B
,Shift + F5
(запуск без отладки) илиF5
(запуск с отладкой));
- Теперь откройте каталог, в котором находится исполняемый файл скомпилированной программы. Если Вы компилировали в конфигурации
Release
то путь будет..\bin\Release
, если вDebug
то..\bin\Debug
; - После открытия каталога, переместите библиотеки
kapi32.dll
иkapi32u.dll
из скачанного репозитория (из папкиModules
) в эту директорию, чтобы исполняемый файл и библиотеки находились в одной папке;
- После этого можно сказать, что Ваш проект полностью настроен и готов к работе с библиотеками
kapi32.dll
иkapi32u.dll
.
В случае проблем с отладкой приложения, попробуйте запустить его непосредственно из папки, в которой располагается исполняемый файл программы. Это должно решить проблему.
Согласование о вызовах нужно указывать именно так, как прописано в примерах импорта функций.
PtrToStr
- Преобразовывает указатель на массив из символов в текст;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static string PtrToStr(IntPtr intPtr);
OpenDataBase
- Открывает локальную базу данных для последующего выполнения к ней запросов;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static bool OpenDataBase(string strDataBase, string strPassword);
EnumTables
- Позволяет перечислить все имеющиеся таблицы в базе данных. Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static string EnumTables();
GetTableCount
- Получает текущее количество таблиц в базе данных. Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static int GetTableCount();
EnumFields
- Позволяет перечислить и получить имена всех полей, которые находятся в таблице, указанной в аргументе функции. Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static string EnumFields(string strTable);
GetFieldCount
- Позволяет получить количество полей в таблице, указанной в аргументе функции. Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static int GetFieldCount(string strTable);
SelectAllFrom
- Извлекает все данные таблицы вместе с полями через запрос "SELECT * FROMTableName
;". Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static string SelectAllFrom(string strTable, bool bOutput);
CreateCustomQuery
- Позволяет выполнять кастомные запросы к базе данных. Для примера "SELECTid
,Password
,UserPC
FROMLibrarians
;". Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static string CreateCustomQuery(string strQuery);
UnloadTable
- Позволяет выгрузить все записи таблицы вместе с полями в какой-либо файл с определёнными разделителями. Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static string UnloadTable(string strTable, string strFile, int iType, bool bOutput);
GetTableRecords
- Получает количество записей в таблице, указанной в аргументе функции. Всегда должна выполняться после вызова OpenDataBase;
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static int GetTableRecords(string strTable);
CloseDataBase
- Закрывает соединение с базой данных. Должна вызываться после завершения работы с базой данных.
Пример импорта:
[DllImport("kapi32.dll", CallingConvention = CallingConvention.StdCall)]
extern public static bool CloseDataBase();
Модуль (библиотека) содержит в себе всего лишь одну экспортируемую функцию. Которая выполняет своё главное действие только один раз.
ScanForPass
- Извлекает из памяти процесса (программы) пароль для базы данных.
Пример импорта:
[DllImport("kapi32u.dll", CallingConvention = CallingConvention.StdCall)]
extern public static IntPtr ScanForPass(string strAppName);
Более детальную информацию с примерами кода и работы с функциями экспорта Вы сможете найти в документации к библиотекам.
- Ссылка на документацию: https://kekekekkek.github.io/KABIS.API/;
- Также, в репозитории хранятся исходные коды программ (в папке
Examples
), которые можно применять на практике для интеграции библиотечной системы с другими корпоративными системами.
Обычно, при выгрузке таблицы с использование функции UnloadTable
, выгружаются только те поля, которые содержатся в той таблице, которую Вы указали в аргументе функции. Например таблица
Books
содержит в себе только такие поля: ID_Book
, Desc_1
, Desc_21
, Desc_29
, Desc_31
, ID_Catalog
, ID_Label
, N_Label
, ID_Librarian
, FirstDate
, LastDate
, Desc_65
,
Bk_GUID
, Deleting
, SortStr
, RecDate
, CopyCnt
, Desc_77
, ID_Librarian2
, но не содержит дополнительных полей, таких как Desc_25
или Desc_32
, которые содержат дополнительную
информацию к описанию книжной записи.
Для решения данной проблемы, Вы можете установить взаимосвязь между таблицами, используя ключевое слово JOIN
при выполнении SQL-запроса.
Для выполнения кастомных запросов к базе данных можно использовать вызов функции CreateCustomQuery
с переданным в неё кастомным запросом.
Наглядную взаимосвязь таблиц можно увидеть на скриншотах ниже:
Получение дополнительных полей для книжной записи в программе КАБИС происходит следующим образом:
- При открытии библиотечной записи в интерфейсе, программа
КАБИС
выполняет запрос к таблицеBookDesc
поID_Book
в которой хранятся все дополнительные поля библиотечной записи, как это можно видеть на скриншотах выше; - После получения полей
ID_Desc
,DescRepNum
иID_Text
из таблицыBookDesc
, программа выполняет запрос к таблицам с наименованиемZDesc_%
(эти таблицы соответствуют дополнительным полям с описанием для библиографической записи), где результат сID_Desc
соответствует номеру поля, которое необходимо отобразить, а полеID_Text
соответствует библиотечной записи (книге), гдеID_Text
для определённой книги соответствует его полюID_Desc
; - После выполнения этих запросов мы и можем видеть тот результат, что продемонстрирован на скриншотах выше. Если Вы хотите извлекать всю дополнительную информацию о книге, включая количество страниц и прочую информацию, можно выполнять подобные запросы с использованием функции
CreateCustomQuery
, что представлены ниже. Пример выполнения запросов внутри программыКАБИС
:
...
public static string[] ParseColumn(string strResult, string strColumn)
{
bool bFind = true;
string[] strValues = new string[0];
if (!string.IsNullOrEmpty(strResult)
&& !string.IsNullOrEmpty(strColumn))
{
int iLine = 0;
int iCurTab = 0, iSaveTab = 0;
int iIndex = strResult.IndexOf(strColumn);
if (iIndex != -1)
{
for (int i = 0; i < strResult.Length; i++)
{
if (strResult[i] == '\t')
{
if (bFind)
iSaveTab++;
iCurTab++;
continue;
}
if (strResult[i] == '\r'
|| strResult[i] == '\n')
{
iLine++;
iCurTab = 0;
Array.Resize(ref strValues, (strValues.Length + 1));
continue;
}
if (i == iIndex)
{
bFind = false;
continue;
}
if (iLine > 0)
{
if (iCurTab == iSaveTab)
strValues[(strValues.Length - 1)] += strResult[i];
}
}
}
}
return strValues;
}
...
...
if (KAPI32.OpenDataBase(strDBPath, strDBPass))
{
Console.WriteLine("База данных была успешно открыта!");
//Выполняем запрос для получения id всех полей для текущей книжной записи по её ID_Book (Как пример - это книга под номером 3588)
string strResult = KAPI32.CreateCustomQuery("SELECT ID_Desc, DescRepNum, ID_Text FROM BookDesc WHERE ID_Book=3588");
/*Также, я написал небольшую функцию парсинга (находится выше), которая парсит значения для определённого
* поля исходя из структуры возврата функции CreateCustomQuery (В будущем постараюсь сделать удобней)*/
string[] strDesc = ParseColumn(strResult, "ID_Desc");
string[] strText = ParseColumn(strResult, "ID_Text");
if (strDesc.Length > 0
&& strText.Length > 0)
{
//Получаем полное описание книжной записи (в данном случае это поля "25" и "32")
for (int i = 0; i < strDesc.Length; i++)
{
//ZDesc_25 (Получаем сведения относящиеся к заглавию)
if (strDesc[i] == "25")
Console.WriteLine("Сведения относящиеся к заглавию: \n" + KAPI32.CreateCustomQuery("SELECT Name FROM ZDesc_25 WHERE ID=" + strText[i]));
//ZDesc_32 (Получаем объем книги (в страницах))
if (strDesc[i] == "32")
Console.WriteLine("Кол-во страниц: \n" + KAPI32.CreateCustomQuery("SELECT Name FROM ZDesc_32 WHERE ID=" + strText[i]));
/*В данном случае, можно вызвать метод Replace у функции CreateCustomQuery (так как тип возврата является string) и заменить
* текст "Name\n" на "", чтобы вывести результат запроса без лишнего текста, простым значением*/
}
}
if (KAPI32.CloseDataBase())
Console.WriteLine("Соединение с базой данных было закрыто.");
}
...
Код продемонстрированный выше является всего лишь примером того, как это можно сделать и как это происходит внутри самой программы КАБИС
.
При помощи этой информации Вы сможете сделать полноценную интеграцию библиотечной программы КАБИС
с другими корпоративными системами. В будущем, я постараюсь сделать получение информации с дополнительных полей библиографической записи немного удобней, без использования того метода, что был продемонстрирован в коде выше.
Вы можете использовать все функции экспорта так, как захотите, всё зависит только от Вашего воображения. Теперь, при помощи данного инструмента у Вас появится возможность интеграции библиотечной системы KABIS с другими корпоративными системами, по крайней мере у меня.
Также, в случае обнаружения проблем библиотеки или проблем при работе с ней, Вы можете задать мне любые вопросы по этому поводу в Discord.