Суббота, 2024-04-27, 9:43 PM
 
|
Курсы валют. Прогноз погоды.
GISMETEO.RU: погода в г. Москва
Вы вошли как "Гость" · RSS Начало Регистрация Вход
Меню

Рубрикатор
ЕНВД [43]
НДС [56]
1C [12]
Бухгалтерия [59]
ЕСН [17]
Управление персоналом [21]
Учет в торговле [27]
Учет в туризме [7]
Учет в строительстве [13]
Учет в СМИ [5]
Учет в НКО [8]
Учет в медицине [3]
Учет у бюджетников [13]
Управленческий учет [9]
НДФЛ [21]
Транспортный налог [10]
МСФО [18]
ККТ, ККМ [9]
ПФР [7]
НДС. Определение КС № 169-0 [16]
Бухучет в банках [21]
Налоги. налогообложение [10]
Госпошлина [7]
Арбитражная практика [22]
Арендные отношения [38]
Учет основных средств и НМА [5]
УСН [5]
Юридические услуги [13]
Образование [1]
Покупка/продажа бизнеса [4]
Forex [2]
Пособия [5]
Лизинг [1]
Экономика [11]
Бизнес-план [1]
Банки [24]
Разное [1]

Партнеры

Счетчики



Rambler's Top100
Яндекс цитирования
Налоги, аудит, финансы, бухучет.
» 2006 » Апрель » 14 » Реализация одного из инструментов отладки 1С Предприятие 8.0
Реализация одного из инструментов отладки 1С Предприятие 8.0
Данная статья описывает реализацию одного из инструментов тестирования и отладки. Рассматривается это на примере идентификации внутренней структуры базы данных 1С Предприятие 8.0.(SQL) для произвольной конфигурации.

Дано : Произвольная конфигурация на базе 1С Предприятие 8.0. (SQL)

Цель : Максимально автоматизировать процесс идентификации внутренней структуры к объектам на уровне приложения.

Реализация :Для начала необходимо понять, как это можно было бы сделать вручную. Очевидно, брать в руки профайлер настраивать трейсы. Изменяя объекты приложения сопоставлять данные в трейсах с соответствующими изменениями объектов. В общем, этот процесс не сложный, но довольно таки трудоемкий и рутинный. На помощь в автоматизации этого процесса нам приходят триггера MSSQL и возможность их динамического создания. Кроме этого, имея возможность определения структуры метаданных как в 1С, так и в MS SQL(системных объектов) мы получаем весь необходимый инструментарий.

Итак, алгоритм автоматизации заключается в выполнении следующих пунктов:

1) Создаем триггера на все объекты MSSQL базы. В реализации триггера указывается запись в отдельную таблицу следующих значений : ИмяТаблицы, ИмяИзмененногоПоля, PK или уникальный индекс измененной записи, ЗначениеИзВременнойТаблицы. В переменную ЗначениеИзВременнойТаблицы будет передаваться из 1С соответствующее изменению в объекте 1С. Собственно говоря, система этих триггеров это есть фактически одна из систем логирования в БД.

2) Реализуем функцию, которая будет передавать в MSSQL значение изменения в объекте 1С. Передавать мы должны таким образом что бы затем можно было получить это значение и присвоить переменной ЗначениеИзВременнойТаблицы в вышеописанной системе триггеров.

3) Организуем циклом перебор метаданных в 1С. Производим последовательное изменение объектов 1С.Передаем в переменную ЗначениеИзВременнойТаблицы конкретное изменение объекта. Передать значение в ЗначениеИзВременнойТаблицы необходимо до выполнения команды изменяющей объект для того что бы триггер получил информацию о том какой объект 1С его вызвал и какие изменения в этом объекте произошли. Собственно говоря, в этом пункте и заключается одна из сложностей не позволяющая этот алгоритм сделать полностью универсальным. Дело в том, что 1С использует агрегацию данных и кроме этого логика изменений зависит от текущего состояния объекта. Если мы изменим, значение одного реквизита в случае, когда документ уже существует в базе и когда этот документ создается впервые в результате получим различный набор команд к SQL серверу. С агрегацией аналогичная ситуация. Предположим у нас есть два одинаковых документа с разницей по дате в год, осуществляющих линейное движение по регистрам(для упрощения без обработки всякой логики). Так вот в случае проведения первого документа мы получим одно количество изменений по агрегационным записям, а случае проведения второго другое количество.

Реализовав подобную систему на выходе, мы получим соответствие объектов 1С к объектам MS SQL. Конечно, нужно понимать, что информация в полученной таблице довольно таки сыра и потребует некоторой обработки. Кроме этого можно составить последовательность операций с метаданными и соответствующую обработку результирующей таблицы, что бы определить автоматически для этой конфигурации внутреннюю структуру данных. Неважно будем мы заново создавать или удалять эту конфигурацию, в какой последовательности создавать в конфигураторе объекты метаданных - подобная система однозначно определит соответствие. Но важно понимать следующее - для любой произвольно взятой конфигурации эта система работать не будет. Точнее она будет работать, но если для этой конфигурации придумать свою систему изменения объектов на основании метаданных и обработки результирующей таблицы. Но этого по большому счету и не нужно. Подобная система это инструмент. С помощью этого инструмента специалист довольно быстро разберется с любой интересующей его структурой.

Ниже я приведу несложный код для автоматической генерации триггеров на БД.

declare @str char(8000)
declare @Table_name char(100)
declare @id int
declare @Column_name char(100)

declare TableCur cursor local fast_forward for -- Декларация курсора
select [name],[id] from sysobjects
where xtype='U' and status>0 and name<>'Log1CforSQL'
-- Запрос по всем таблица в текущей БД кроме той куда пишется лог
open TableCur -- Открытие крсора
fetch TableCur into @Table_name,@id
while (@@fetch_status<>-1) -- Цикл по курсору
begin
set @str='if exists (select * from dbo.sysobjects where id =
object_id(N''[dbo].[TR_U_'+rtrim(@Table_name)+']'')
and OBJECTPROPERTY(id, N''IsTrigger'') = 1)
drop trigger [dbo].[TR_U_'+rtrim(@Table_name)+']' -- удаляем если он уже существует
exec (@str)
select @str='CREATE TRIGGER [TR_U_'+rtrim(@Table_name)+'] ON [dbo].['+rtrim(@Table_name)+']
FOR Update
AS
set nocount on
declare @Izm1CObject char(1000)
select @Izm1CObject=Izm1CObject from BufferIzm1CObject where spid=@@spid '

declare ColumnCur cursor local fast_forward for
select [name] from syscolumns -- Запрос по списку колонок конкретной таблицы
where [id] = @id
open ColumnCur -- Открытие курсора
fetch ColumnCur into @Column_name
while (@@fetch_status<>-1)
begin
select @str =rtrim(@str)+' if update('+@Column_name+')
begin insert into Log1CforSQL(TableName,ColumnName,Izm1CObject,Type)
values('''+rtrim(@Table_name)+''','''+rtrim(@Column_name)+''',@Izm1CObject,''U'') end'
--Вообще то признак update не гарантирует того что поле изменилось(в 7.7. так и происходило)
--поэтому здесь необходимо сравнивать deleted и inserted , данный вариант - некоторое упрощение
fetch ColumnCur into @Column_name
end
select @str =rtrim(@str)+' set nocount off'
close ColumnCur
deallocate ColumnCur
--Создание триггеров на удаление и вставку.
--Если текст для создания триггера будет более 8000 символо то этот алгоритм работать не бдет
--Вообще то для этих случаев необходимо создавать текст триггера через временную таблицу например
-- В данном случае так реализованно для простоты понимания
exec (@str)
set @str='if exists (select * from dbo.sysobjects where id =
object_id(N''[dbo].[TR_D_'+rtrim(@Table_name)+']'')
and OBJECTPROPERTY(id, N''IsTrigger'') = 1)
drop trigger [dbo].[TR_D_'+rtrim(@Table_name)+']' -- удаляем если он уже существует
exec (@str)
select @str= 'CREATE TRIGGER [TR_D_'+rtrim(@Table_name)+'] ON [dbo].['+rtrim(@Table_name)+']
FOR DELETE
AS
set nocount on
declare @Izm1CObject char(1000)
select @Izm1CObject=Izm1CObject from BufferIzm1CObject where spid=@@spid
insert into Log1CforSQL(TableName,ColumnName,Izm1CObject,Type)
values('''+rtrim(@Table_name)+''',''ALL'',@Izm1CObject,''D'')
set nocount off'
exec (@str) -- создаем триггер
set @str='if exists (select * from dbo.sysobjects where id =
object_id(N''[dbo].[TR_I_'+rtrim(@Table_name)+']'')
and OBJECTPROPERTY(id, N''IsTrigger'') = 1)
drop trigger [dbo].[TR_I_'+rtrim(@Table_name)+']' -- удаляем если он уже существует
exec (@str)
select @str= 'CREATE TRIGGER [TR_I_'+rtrim(@Table_name)+'] ON [dbo].['+rtrim(@Table_name)+']
FOR INSERT
AS
set nocount on
declare @Izm1CObject char(1000)
select @Izm1CObject=Izm1CObject from BufferIzm1CObject where spid=@@spid
insert into Log1CforSQL(TableName,ColumnName,Izm1CObject,Type)
values('''+rtrim(@Table_name)+''',''ALL'',@Izm1CObject,''I'')
set nocount off'
exec (@str)-- создаем триггер

fetch TableCur into @Table_name,@id -- Передача названия таблицы из курсора в переменную @Table_name
end
close TableCur
deallocate TableCur


Налоги, бухучет, финансы для клерка

Категория: 1C | Просмотров: 1604 | Добавил: клерк | Дата:
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]