Данный модуль / библиотека (.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,UserPCFROMLibrarians;". Всегда должна выполняться после вызова 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.