Про меню в iScala и таблицу ScaMenuDescr

Автор Сообщение
Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 11.07.2013 12:47 Заголовок сообщения: Про меню в iScala и таблицу ScaMenuDescr
Добрый день.

Столкнулся с проблемой… В таблице ScaMenuDescr базы ScaSystemDB хранится описание (на различных языках) только для фолдеров (Menu Folder) скаловской системы меню.
А кто знает где искать описание для вызываемых элементов (Menu Actions) которые хранятся в этих фолдерах?
Пример чтобы было понятней:

select * from ScaMenuDescr where LangCode = ‘ENG’ order by 1

Запрос выше возварщает названия директориев начиная со стандартного меню:
10001 ENG Standard Menu
10002 ENG General Ledger
10003 ENG Chart of Accounts/Enquiries
10004 ENG Enquire General Ledger
10010 ENG Chart of Accounts
10015 ENG Transactions
И т.д.

В таблице ScaMenuDescr отсутствуют “actions”:
10005 – Enquire General Ledger
10006 – Enquire Transactions
10007 – Enquire Transactions Lines
10008 — Display Currency Account Balance
10009 – Enquire Project History

Кто разбирался, подскажите, где их искать?

P.S. iScala 2.3 SR3 HF 13334

Последний раз редактировалось: Andrejs (24.07.2013 16:12), всего редактировалось 2 раз(а)

Jugulator
Главный форумщик

Зарегистрирован: 08.10.2004
Сообщения: 428

Добавлено: 11.07.2013 14:39 Заголовок сообщения:
Для отчетов можно связывать следующие таблицы в системной базе iScala (по умолчанию ScaSystemDB):

    ScaActions
    ScaMenus
    ScaMenuAssignments
    ScaUsers
    ScaCompanies

Тогда можно показать какое действие запускает пользователь через пункт меню.

Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 23.07.2013 12:27 Заголовок сообщения:
Оказалось сложнее, чем ожидал.

Есть таблица ScaActionDescr. В ней присутствуют недостающие Actions. (Jugulator спасибо за наводку)

select * from ScaActionDescr where LangCode =’ENG’ order by 1

10001 ENG Enquire General Ledger
10002 ENG Enquire Transactions
10003 ENG Enquire Transaction Lines
10004 ENG Display Currency Account Balance
10005 ENG Enquire Project History
и т.д.

Проблема в том, что вместо ожидаемой сквозной нумерации 10005, 10006, и т.д. эти Actions нумеруются своим счетчиком с “нуля”.

Вопрос, через какую таблицу мне это связать с данными из ScaMenuDescr которая хранит названия директориев, в которых эти Actions расположены?

select * from ScaMenuDescr where LangCode = ‘ENG’ order by 1

10001 ENG Standard Menu
10002 ENG General Ledger
10003 ENG Chart of Accounts/Enquiries
10004 ENG Enquire General Ledger
10010 ENG Chart of Accounts
и т.д.

Если глобально, то стоит задача через SQL запрос получить скаловское меню с директориями и Actions.

Последний раз редактировалось: Andrejs (24.07.2013 16:14), всего редактировалось 1 раз

Serj
Заслуженный форумщик

Зарегистрирован: 15.12.2006
Сообщения: 90
Откуда: Санкт-Петербург

Добавлено: 24.07.2013 08:13 Заголовок сообщения:

Andrejs писал(а):
Проблема в том, что вместо ожидаемой сквозной нумерации 10005, 10006, и т.д. эти Actions нумеруются своим счетчиком с “нуля”.

Странно, Вот мой результат запроса:
select *
from ScaActions left join
ScaActionDescr on ID=ItemID
where LangCode=’ENG’

———————————————————————————-
ID | Action | Typ |Param| ItemID |LangCode| Text
10001 | GL016 | 0 | 1 | 10001 | ENG | Enquire General Ledger
10002 | GL016 | 0 | 2 | 10002 | ENG | Enquire Transactions
10003 | GL016 | 0 | 3 | 10003 | ENG | Enquire Transaction Lines
10004 | GL016 | 0 | 4 | 10004 | ENG | Display Currency Account Balance
10005 | GL019 | 0 | | 10005 | ENG | Enquire Project History
10006 | GL001 | 0 | 1 | 10006 | ENG | Enter/Change Accounting Dimension

Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 24.07.2013 16:07 Заголовок сообщения:
1. Что странно?
2. Ваш запрос возвращает Menu Actions. У меня задача скрестить таблицу ScaMenuDescr (Menu Folders) c таблицей ScaActionDescr (Menu Actions)

Если глобально, то стоит задача через SQL запрос получить скаловское меню. Т.е полное меню с директориями (Menu Folders) и объектами внутри этих директориев (Menu Actions).

Как-то так… Smile

Последний раз редактировалось: Andrejs (25.07.2013 23:36), всего редактировалось 1 раз

Serj
Заслуженный форумщик

Зарегистрирован: 15.12.2006
Сообщения: 90
Откуда: Санкт-Петербург

Добавлено: 25.07.2013 09:23 Заголовок сообщения:
Извините, не понял задачи.
Пробуйте это:

select *
from ScaMenus left join
(select * from ScaMenuDescr where LangCode=’ENG’)m on ParentID=m.ItemID left join
(select * from ScaActionDescr where LangCode=’ENG’)a on ActionID=a.ItemID
order by ScaMenus.ID

Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 25.07.2013 23:28 Заголовок сообщения:
Спасибо Serj.

Чуть-чуть подправил Ваш запрос.
Этот джойн не совсем верный: left join (select * from ScaMenuDescr where LangCode=’ENG’) m on ParentID=m.ItemID
Нужно джойнить ID c m.ItemID

В итоге получилось то, что искал. Спасибо за помощь.

Код:
SELECT
CASE
   WHEN x.NodeType=’1′ THEN ‘Menu Folder’
   WHEN x.NodeType=’0′ THEN ‘Menu Action’
   ELSE ‘Unknown’
END AS [Type],
x.ID,
m.Text AS [Folder Name],
x.ActionID,
a.Text AS [Action Name],
x.ParentID
FROM ScaMenus x
LEFT OUTER JOIN (SELECT * FROM ScaMenuDescr WHERE LangCode=’ENG’) m ON x.ID = m.ItemID
LEFT OUTER JOIN (SELECT * FROM ScaActionDescr WHERE LangCode=’ENG’) a ON x.ActionID = a.ItemID
ORDER BY x.ID


Serj
Заслуженный форумщик

Зарегистрирован: 15.12.2006
Сообщения: 90
Откуда: Санкт-Петербург

Добавлено: 26.07.2013 09:45 Заголовок сообщения:
А можно и поиграть с циклами для более красивой картины.
Но время выполнения запроса при этом просто зашкаливает (40 сек только для стандартного меню).

Код:
declare @tmp table(ID int, Typ varchar(10), ParentID int, Descr varchar(200), Level int, Srt varchar(500))
declare @menu table(id int, parid int, descr varchar(200),typ varchar(10))

declare @Level int
set @Level=0

insert into @menu
select x.ID, x.ParentID, isnull(m.Text,a.Text) [Name],
   case
      when x.NodeType=’1′ then ‘Folder’
      when x.NodeType=’0′ then ‘Action’
      else ‘Unknown’
   end
from ScaMenus x
   left outer join (select * from ScaMenuDescr where LangCode=’ENG’) m ON x.ID = m.ItemID
   left outer join (select * from ScaActionDescr where LangCode=’ENG’) a ON x.ActionID = a.ItemID
order by x.ID

insert @tmp(ID, Typ, ParentID, Descr, Level,Srt)
select id, typ, parid, descr, 0,right(’00000’+cast(ROW_NUMBER() over(order by descr) as varchar(100)),5)
FROM @menu
where id=10001—parid is null
order by descr

while exists(select * from (select * from @tmp where Level=@Level) T inner join @menu TR ON T.ID=TR.parid) begin
  insert @tmp(ID, Typ, Descr, ParentID, Level,Srt)
  select TR.id, TR.typ, space((@Level+1)*2)+TR.descr, TR.parid, @Level+1,
   T.Srt+right(’00000’+cast(row_number() over(order by descr) as varchar(100)),5)+cast(id as varchar(100))
  from (select * from @tmp where Level=@Level) T inner join @menu TR on T.ID=TR.parid
  set @Level=@Level+1
end

select * from @tmp order by Srt

Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 26.07.2013 12:02 Заголовок сообщения:
О! Не ожидал…
У меня где-то было как Parent/Child раскладывать, но решил возиться не буду… А у вас так быстро получилось… Класс! Very Happy

P.S. На моем сервере 5 сек для Standard Menu

Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 26.07.2013 12:28 Заголовок сообщения:
Параллельный вопрос… Можно ли из 0-го Стандартного Меню что-либо удалить (специально/случайно)?
Сколько строк у вас возвращает запрос выше? У меня 2988 строк.
Dmitry Pestov
Заслуженный форумщик

Зарегистрирован: 21.06.2007
Сообщения: 94
Откуда: Москва, ApicoSoft

Добавлено: 26.07.2013 14:46 Заголовок сообщения:
О, мне тоже стало интересно. Мой вариант (MS SQL 2005+):

Код:
;with menu as (
  select mp.*, 0 MenuLevel,
  cast(right(’0000000000′ + cast(mp.OrderID as varchar(10)), 10) as varchar(1000)) SortID
  from ScaMenus mp
  where ParentID is null and ID = 10001
  union all
  select mc.*, menu.MenuLevel + 1 MenuLevel,
  cast(menu.SortID + right(’0000000000′ + cast(mc.OrderID as varchar(10)), 10) as varchar(1000)) SortID
  from ScaMenus mc
  join menu on menu.ID = mc.ParentID
)
select menu.ID, case when menu.NodeType = 0 then ‘Action’ else ‘Folder’ end [Type],
menu.ParentID, menu.MenuLevel,
space(menu.MenuLevel * 2) + case when menu.NodeType = 0 then a.[Text] else d.[Text] end Descr,
c.[Action], c.[Type], c.[Param]
from menu
left join ScaMenuDescr d on d.ItemID = menu.ID and d.LangCode = ‘ENG’
left join ScaActionDescr a on a.ItemID = menu.ActionID and a.LangCode = ‘ENG’
left join ScaActions c on c.ID = menu.ActionID and menu.NodeType = 0
order by menu.MenuID, menu.SortID, menu.OrderID


Как бы сделать сортировку по-проще?
_________________
Dmitry Pestov

Блог ScalaHelp.RU — практические вопросы использования Scala

aav
Администратор
Администратор

Зарегистрирован: 14.09.2004
Сообщения: 1081
Откуда: Санкт-Петербург

Добавлено: 28.07.2013 11:33 Заголовок сообщения: Re: Про меню в iScala и таблицу ScaMenuDescr
А дальше что? Что Вы собираетесь с этим делать? Как использовать? Для чего Вам это? В чём состоит идея?
Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 02.09.2013 23:09 Заголовок сообщения:
Мы используем меню для регулирования доступа пользователей к имеющемуся в iScala функционалу.
Назначение меню той или иной роли проходит согласование, само меню тоже согласовывается, распечатывается и подписывается. Т.к. из скалы меню не распечатаешь пришлось приседать с SQL запросом.
Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 13.09.2013 00:56 Заголовок сообщения:
Помогите с NULL разобраться. В возвращаемом массиве данных я хочу убрать NULL из столбца Action. Причем хочу заменить NULL на значение из столбца MenuLevel.

Изменил c.[Action] в запросе Dmitry такой строчкой:
case when c.[Action] is null then menu.MenuLevel else c.[Action] end as [Action]

При выполнении запроса получаю ошибку:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the nvarchar value ‘GL016’ to data type int.

Что я не так с case when делаю?

Dmitry Pestov писал(а):
О, мне тоже стало интересно. Мой вариант (MS SQL 2005+):

Код:
;with menu as (
  select mp.*, 0 MenuLevel,
  cast(right(’0000000000′ + cast(mp.OrderID as varchar(10)), 10) as varchar(1000)) SortID
  from ScaMenus mp
  where ParentID is null and ID = 10001
  union all
  select mc.*, menu.MenuLevel + 1 MenuLevel,
  cast(menu.SortID + right(’0000000000′ + cast(mc.OrderID as varchar(10)), 10) as varchar(1000)) SortID
  from ScaMenus mc
  join menu on menu.ID = mc.ParentID
)
select menu.ID, case when menu.NodeType = 0 then ‘Action’ else ‘Folder’ end [Type],
menu.ParentID, menu.MenuLevel,
space(menu.MenuLevel * 2) + case when menu.NodeType = 0 then a.[Text] else d.[Text] end Descr,
c.[Action], c.[Type], c.[Param]
from menu
left join ScaMenuDescr d on d.ItemID = menu.ID and d.LangCode = ‘ENG’
left join ScaActionDescr a on a.ItemID = menu.ActionID and a.LangCode = ‘ENG’
left join ScaActions c on c.ID = menu.ActionID and menu.NodeType = 0
order by menu.MenuID, menu.SortID, menu.OrderID

vome
Народный форумщик

Зарегистрирован: 17.09.2004
Сообщения: 210
Откуда: Санкт-Петербург -> Москва

Добавлено: 13.09.2013 08:58 Заголовок сообщения:

Andrejs писал(а):
При выполнении запроса получаю ошибку:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the nvarchar value ‘GL016’ to data type int.

Ну так Вам четко говорят, "не могу преобразовать значение ‘GL016’ в число". И это действительно так.
Замените в запросе

Код:
case when c.[Action] is null then cast(menu.MenuLevel as nvarchar(10)) else c.[Action] end as [Action]


Как я подозреваю именно поле menu.MenuLevel выдает значение в числовом формате.
а можно еще проще:

Код:
ISNULL(c.[Action],cast(menu.MenuLevel as nvarchar(10))) AS [Action]

Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 13.09.2013 10:07 Заголовок сообщения:
Помогло! Спасибо.
Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 14.09.2013 00:46 Заголовок сообщения:
Еще задачка… Embarassed

В меню, для разных iScala модулей (General Ledger, Fixed Assets и т.д.) есть повторяющиеся элементы. Причем встречаются они порой на той же самой „глубине”.

Например, в General Ledger, на втором уровне, есть фолдер Miscellaneous. В Fixed Assets есть фолдер с точно таким же названием Miscellaneous и на том же втором уровне.

Мне нужно иметь возможность отличить, какому модулю принадлежит тот или иной элемент меню.

Есть ли возможность дополнить запрос Dmitry так, чтобы это было видно?
Например, дополнительный столбец, который содержит название модуля iScala и меняет свое занчение только при переходе в следующий модуль?

Dmitry Pestov
Заслуженный форумщик

Зарегистрирован: 21.06.2007
Сообщения: 94
Откуда: Москва, ApicoSoft

Добавлено: 14.09.2013 15:50 Заголовок сообщения:
Можно вывести полный путь к каждой команде

Код:
;with menu as (
  select mp.*, 0 MenuLevel,
  cast(right(’0000000000′ + cast(mp.OrderID as varchar(10)), 10) as varchar(1000)) SortID,
  cast(» as varchar(2000)) MenuFolder
  from ScaMenus mp
  where ParentID is null and ID = 10001
  union all
  select mc.*, menu.MenuLevel + 1 MenuLevel,
  cast(menu.SortID + right(’0000000000′ + cast(mc.OrderID as varchar(10)), 10) as varchar(1000)) SortID,
  cast(menu.MenuFolder + case when len(menu.MenuFolder) > 0 then ‘->’ else » end +
  (select d.[Text] from ScaMenuDescr d where d.ItemID = menu.ID and d.LangCode = ‘ENG’) as varchar(2000)) MenuFolder
  from ScaMenus mc
  join menu on menu.ID = mc.ParentID
)
select menu.ID, case when menu.NodeType = 0 then ‘Action’ else ‘Folder’ end [Type],
menu.ParentID, menu.MenuLevel,
space(menu.MenuLevel * 2) + case when menu.NodeType = 0 then a.[Text] else d.[Text] end Descr,
c.[Action], c.[Type], c.[Param], menu.MenuFolder
from menu
left join ScaMenuDescr d on d.ItemID = menu.ID and d.LangCode = ‘ENG’
left join ScaActionDescr a on a.ItemID = menu.ActionID and a.LangCode = ‘ENG’
left join ScaActions c on c.ID = menu.ActionID and menu.NodeType = 0
order by menu.MenuID, menu.SortID, menu.OrderID


Результат:

Код:
 Type   ParentID    MenuLevel   Descr                                      Action  Type Param  MenuFolder
———————————————————————————————————-
 Folder NULL        0           Standard Menu                              NULL    NULL NULL   
 Folder 10001       1             General Ledger                           NULL    NULL NULL   Standard Menu
 Folder 10002       2               Chart of Accounts/Enquiries            NULL    NULL NULL   Standard Menu->General Ledger
 Folder 10003       3                 Enquire General Ledger               NULL    NULL NULL   Standard Menu->General Ledger->Chart of Accounts/Enquiries
 Action 10004       4                   Enquire General Ledger             GL016   0    1      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Enquire General Ledger
 Action 10004       4                   Enquire Transactions               GL016   0    2      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Enquire General Ledger
 Action 10004       4                   Enquire Transaction Lines          GL016   0    3      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Enquire General Ledger
 Action 10004       4                   Display Currency Account Balance   GL016   0    4      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Enquire General Ledger
 Action 10003       3                 Enquire Project History              GL019   0           Standard Menu->General Ledger->Chart of Accounts/Enquiries
 Folder 10003       3                 Chart of Accounts                    NULL    NULL NULL   Standard Menu->General Ledger->Chart of Accounts/Enquiries
 Action 10010       4                   Enter/Change Accounting Dimension  GL001   0    1      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Chart of Accounts
 Action 10010       4                   Delete Accounting Dimension        GL001   0    2      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Chart of Accounts
 Action 10010       4                   Enter/Change Foreign Descriptions  GL001   0    3      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Chart of Accounts
 Action 10010       4                   Enter/Change Coding Combinations   GL001   0    4      Standard Menu->General Ledger->Chart of Accounts/Enquiries->Chart of Accounts
 Folder 10002       2               Transactions                           NULL    NULL NULL   Standard Menu->General Ledger
 Action 10015       3                 Enter Transactions                   GL003   0           Standard Menu->General Ledger->Transactions
 Action 10015       3                 Print GL Coding Slip                 GL003P  0           Standard Menu->General Ledger->Transactions
 Action 10015       3                 Print DayBook Journal                GL004   0           Standard Menu->General Ledger->Transactions


_________________
Dmitry Pestov

Блог ScalaHelp.RU — практические вопросы использования Scala

Andrejs
Старший форумщик

Зарегистрирован: 22.03.2013
Сообщения: 21
Откуда: Latvia

Добавлено: 14.09.2013 22:48 Заголовок сообщения:
Подходит! Спасибо!
aav
Администратор
Администратор

Зарегистрирован: 14.09.2004
Сообщения: 1081
Откуда: Санкт-Петербург

Добавлено: 17.04.2017 09:22 Заголовок сообщения: Отчёт на базе предложенного запроса
http://scala.org.ru/report-examples-30/
Не забудьте прочитать комментарий на счёт русских букв Very Happy