Глава 6. БАЛАНС
Работа со счетами, системные хранимые процедуры ACC_TREE, ACC_PARENTS, ACC_ROOT
Зная устройство таблицы счетов ACC, мы можем при помощи
SQL-запросов выбирать необходимые группы счетов. Предположим,
что имеется складской регистр «Товары на складах», в
котором заведены дочерние счета «Главный склад», «Магазин
на ул. Парковой, 2», «Магазин на
ул. Пушкинской, 5». Простейший способ запросить все
имеющиеся склады:
select acc_id, parent_id, name
from acc
where parent_id = 115;
Результат запроса:
ACC_ID |
PARENT_ID |
NAME |
123 |
115 |
Главный склад |
117 |
115 |
Магазин на ул.Парковой 2 |
207 |
115 |
Магазин на ул.Пушкинской, 5 |
В данном случае ACC_ID = 115 - это
идентификатор счета «Товары на складах», являющегося непосредственным родительским
счетом (счетом-каталогом) для счетов конкретных складов
. Такой запрос может нам понадобиться, например, если
нужно организовать выпадающий список всех имеющихся складов в каком-
либо окне, где пользователь вносит какие-то данные
.
Разумеется, такой простой запрос позволяет лишь запросить все дочерние
счета одного уровня. А как нам действовать, если
нужно получить субсчета всех уровней для какого-то счета
? Для этого имеется хранимая процедура ACC_TREE,
возвращающая все сочетания старший счет-младший счет для всех
уровней дерева.
Результирующий набор, поставляемый хранимой процедурой ACC_TREE
Название поля |
Тип данных |
Назначение |
ACC_ID |
INTEGER |
Внутренний ID счета |
CHILD_ID |
INTEGER |
Внутренний ID счета-потомка |
SALDO_KIND |
SMALLINT |
Тип сальдо (для запросов баланса компании) |
TURN_KIND |
SMALLINT |
Тип оборотов (для запросов баланса компании) |
Процедура ACC_TREE для каждого счета ACC_ID
возвращает парные сочетания его самого и всех его потомков CHILD
_ID, независимо от уровня вложенности. Некоторые одинаковые
комбинации ACC_ID, CHILD_ID встречаются несколько
раз и отличаются значениями SALDO_KIND и TURN_
KIND, которые используются при запросе баланса компании (сейчас
мы их назначение рассматривать не будем). Важно то,
что, используя процедуру ACC_TREE, мы можем
легко получить ID всех дочерних счетов для счета с ID
=115, написав такой запрос:
select distinct child_id
from acc_tree
where (acc_id = 115) and (child_id <> 115)
Условие (child_id <> 115) мы ввели
для того, чтобы исключить из выходного набора сам родительский
счет ACC_ID = 115. Слово distinct устраняет
дубликаты, которые поставляются процедурой ACC_TREE и в
данном случае нам не нужны.
Если мы хотим получить не только ID счетов, но
и их названия, объединим результат работы процедуры ACC_
TREE с таблицей счетов ACC:
select distinct a.acc_id, a.name
from acc_tree atr, acc a
where
a.acc_id = atr.child_id and
atr.acc_id = 115
Используя запросы, мы можем гарантировать, что в выпадающем
списке «Выберите склад» всегда будут отображаться все нужные
счета, даже если пользователь сам добавит новый счет в
регистр (например, в случае возникновения нового склада «
Магазин на ул. Чехова, 13»).
Еще необходимо упомянуть о системной хранимой процедуре ACC_PARENTS
. Эта процедура используется процедурой ACC_TREE для построения
всех сочетаний счетов вида старший-младший, но мы
можем иногда ее применять и для своих целей. Процедура
ACC_PARENTS имеет один входной параметр CHILD_ID
типа INTEGER, поэтому вызывать ее следует с входным параметром
. Процедура ACC_PARENTS возвращает всех предков счета,
включая его самого плюс, признаки SALDO_KIND и
TURN_KIND, которые сейчас нас не интересуют.
Важно то, что один и тот же счет процедура
может вернуть несколько раз, поэтому рекомендуется использовать в запросах
слово distinct.
Результирующий набор, поставляемый хранимой процедурой ACC_PARENTS
Название поля |
Тип данных |
Назначение |
PARENT_ID |
INTEGER |
Внутренний ID счета |
SALDO_KIND |
SMALLINT |
Тип сальдо (для запросов баланса компании) |
TURN_KIND |
SMALLINT |
Тип оборотов (для запросов баланса компании) |
Например, запросим всех предков счета с ACC_ID
= 1083
select distinct parent_id
from acc_parents(1083)
Если нам нужны не только ID счетов, но и
их имена, то можем объединить результаты работы процедуры ACC
_PARENTS с таблицей счетов:
select distinct a.acc_id, a.name
from acc_parents(1083) ap, acc a
where ap.parent_id = a.acc_id
Примерный результат запроса:
ACC_ID |
NAME |
1 |
Средства |
3 |
Оборотные средства |
1078 |
Денежные средства |
1083 |
Касса, Пушкинская 5 |
Запрос всех предков счета, который мы привели, может
понадобиться достаточно редко, чаще бывает нужно выяснить свойства регистра
для какого-то выбранного счета. Для того чтобы
узнать свойства регистра, к которому принадлежит счет, можно
, конечно воспользоваться процедурой ACC_PARENTS, объединив результаты
запроса с таблицей ACC_ROOTS:
select distinct
ar.acc_id, ar.root_kind, ar.class_id, ar.use_quantity,
ar.color, ar.font_name, ar.font_size, ar.object_tree, ar.right_hand
from acc_parents(1083) ap, acc_roots ar
where ap.parent_id = ar.acc_id
Иногда проще часть этой информации получить, используя системную хранимую
процедуру ACC_ROOT. Эта процедура имеет входной параметр
ACC_ID типа INTEGER. При вызове с помощью
этого параметра процедуре мы передаем ID счета, регистр которого
нас интересует.
Результирующий набор, поставляемый хранимой процедурой ACC_ROOT
Название поля |
Тип данных |
Назначение |
ROOT_ID |
INTEGER |
Внутренний ID счета |
ROOT_KIND |
SMALLINT |
Тип регистра:
0 – левой стороны баланса
1 – правой стороны баланса
2 – балансового регистра
3 – забалансового регистра |
ROOT_QUANTITY |
|
Признак количественного учета:
0 – без количественного учета
1 – используется количественный учет |
ROOT_CLASS_ID |
INTEGER |
Внутренний ID класса справочника, привязанного к регистру |
OBJECT_TREE |
SMALLINT |
Отображать дерево объектов (для небольших справочников)
0
– не отображать дерево
1 – отображать дерево |
RIGHT_HAND |
SMALLINT |
Способ отображения остатков на счетах регистра:
0 –
левосторонний регистр
1 – правосторонний регистр |
Пример использования хранимой процедуры ACC_ROOT:
select * from acc_root(1083);
Этот SQL-запрос вернет нам одной строкой все важные
сведения о регистре, в который входит счет 1083.
|