Автоматизируем подключение баз «1С» новой версии 8.0::Журнал СА 7.2005
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Наука и технологии
Подписка
Где купить
Авторам
Рекламодателям
Архив номеров
Контакты
   

  Опросы
  Статьи

Электронный документооборот  

5 способов повысить безопасность электронной подписи

Область применения технологий электронной подписи с каждым годом расширяется. Все больше задач

 Читать далее...

Рынок труда  

Системные администраторы по-прежнему востребованы и незаменимы

Системные администраторы, практически, есть везде. Порой их не видно и не слышно,

 Читать далее...

Учебные центры  

Карьерные мечты нужно воплощать! А мы поможем

Школа Bell Integrator открывает свои двери для всех, кто хочет освоить перспективную

 Читать далее...

Гость номера  

Дмитрий Галов: «Нельзя сказать, что люди становятся доверчивее, скорее эволюционирует ландшафт киберугроз»

Использование мобильных устройств растет. А вместе с ними быстро растет количество мобильных

 Читать далее...

Прошу слова  

Твердая рука в бархатной перчатке: принципы soft skills

Лауреат Нобелевской премии, специалист по рынку труда, профессор Лондонской школы экономики Кристофер

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 9956
Комментарии: 0
Потоковая обработка данных

 Читать далее...

19.03.2018г.
Просмотров: 8164
Комментарии: 0
Релевантный поиск с использованием Elasticsearch и Solr

 Читать далее...

19.03.2018г.
Просмотров: 8264
Комментарии: 0
Конкурентное программирование на SCALA

 Читать далее...

19.03.2018г.
Просмотров: 5233
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 5920
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

Друзья сайта  

 Автоматизируем подключение баз «1С» новой версии 8.0

Архив номеров / 2005 / Выпуск №7 (32) / Автоматизируем подключение баз «1С» новой версии 8.0

Рубрика: Базы данных /  Изучаем «1С»   | Дополнительные материалы

ИВАН КОРОБКО

Автоматизируем подключение баз «1С» новой версии 8.0

Специалисты компании «1С» значительно переработали систему безопасности в базах «1С» новой версии 8.0 по сравнению с прошлой «1С» 7.7. В связи с этим архитектура программы изменилась коренным образом. Как следствие стал иным и механизм подключения баз

Мы уже знакомили вас с автоматическим управлением подключения баз «1С» v.7.7 с помощью сценария регистрации пользователей в сети (см. [1]). Пользователям, которые входили в соответствующие группы безопасности, сценарий автоматически подключал необходимые сетевые базы и отключал те, к которым пользователь не имел прав доступа, при этом подключенные локальные базы сценарием не затрагивались. С появлением «1С» v.8.0 ситуация изменилась: сценарий для подключения баз «1С» v.7.7 не подходит для новой версии «1С», поскольку информация о подключаемых базах для версии 7.7 хранилась в системном реестре на рабочей станции, а для версии 8.0 – в файлах. Сегодня мы подробно рассмотрим механизм подключения баз «1С» v.8.0, ее итогом будет сценарий, который в автоматическом режиме управляет подключением сетевых баз, записи, соответствующие в браузере локальным базам, будут перенесены в отдельную папку.

Выбираем язык программирования

Для создания сценариев регистрации пользователей существует множество языков, однако остановим свой выбор на KIXTart. Этот язык является стандартным языком программирования сценариев компании Microsoft. Его дистрибутив можно найти в Microsoft Resource Kit или бесплатно загрузить последнюю версию из сети Интернет (http://kixtart.org). Подробное описание функционала языка можно найти на этом же сайте.

Замечание: сценарии, созданные вами ранее на VBScript, Jscript, могут быть легко переписаны под KIXtart.

Рассмотрим внутреннее устройство клиентской части 1C v.8.0

Как было сказано ранее, информация о подключенных базах для версий 7.7 и 8.0 находится в разных местах. Теперь все данные хранятся в каталоге «Documents and Settings\%username% Application Data1C1Cv8». Для успешного подключения баз необходимо в нем создать минимум два файла (1Cv8strt.pfl и v8ib.lst) и соответствующие ID баз папки. В каждой из них также должен быть создан файл usr.def. Файловая структура подключаемых баз приведена на рис. 1.

Рисунок 1. Файловая структура клиентской части «1С» 8.0

Рисунок 1. Файловая структура клиентской части «1С» 8.0

Управление отображением списка баз (визуальная структура) в браузере «1С» осуществляется с помощью файла v8ib.lst  (рис. 2). С помощью второго файла – 1Cv8strt.pfl реализовано манипулирование такими параметрами, как размер и положение браузера «1С» на экране, сортировка списка баз и т.д. В файле usr.def содержится имя пользователя, который последний открывал данную информационную базу. Все три файла имеют кодировку utf-8, и соответственно создавать их необходимо именно в этой кодировке. В противном случае данные в браузере «1С» будут отображаться некорректно либо не будут отображаться вовсе.

Рисунок 2. Браузер «1С»

Рисунок 2. Браузер «1С»

Управляем текстовыми файлами в кодировке utf-8

Объект FSO, традиционно используемый для создания текстовых файлов, не подходит, поскольку он не поддерживает требуемой кодировки (utf-8). Для решения поставленной задачи предлагается использовать объект ADODB.Stream. Управление текстовыми файлами подразумевает чтение и запись данных в файл. Приведу два соответствующих примера. Чтение данных из текстового файла:

$Stream = CreateObject("ADODB.Stream")

$Stream.Type =2

$Stream.CharSet = "Utf-8"

$Stream.Open

$Stream.LoadFromFile("1.txt")

$GetFile = $Stream.Readtext()

$Stream.Close

В примере данные считываются из файла 1.txt в переменную $GetFile. Параметр $Stream.Type может принимать значения 1(binary) или 2(text), в зависимости от типа данных, содержащихся в файле. С помощью параметра $Stream.CharSet управляют кодировкой чтения/записи данных в файл. Доступные для данной ОС кодировки перечислены в системном реестре HKEY_CLASSES_ROOTMIMEDatabaseCharset.

Запись данных в текстовый файл:

$Stream = CreateObject("ADODB.Stream")

$Stream.CharSet = "utf-8"

$Stream.Mode = 3

$Stream.Open

$Stream.WriteText("Записываемые данные")

$Stream.SaveToFile("1.txt")

$Stream.Close

В приведенном примере данные, на которые ссылается функция Stream.WriteText(), записываются в файл 1.txt; С помощью параметра $Stream.Mode осуществляется управление режимом работы с данными файла. Основные принимаемые значения – 1 (чтение – по умолчанию), 2 (запись) и 3 (чтение/запись).

Структура файла v8ib.lst

В файле v8ib.lst содержащиеся данные описывают один из двух объектов: папку или ссылку на базу. Существуют ссылки на локальную или серверную базу. Описываемый файл имеет структуру ini-файла, названия разделов в котором совпадают с именами баз, отображаемыми в браузере.

Синтаксис баз

Как уже говорилось, название разделов должно совпадать с соответствующими именами баз. В каждом разделе присутствует пять обязательных параметров, описания которых приведены в таблице 1.

Таблица 1. Описание параметров, используемых в файле v8ib.lst

Параметр

Описание

Connect

Значением параметра является путь к базе данных. Для локальной базы значение формируется в соответствии с шаблоном File=”путь к локальной базе”; для сетевой – srvr=”sql_server.domain”; ref=”название базы данных на SQL-сервере”;

ID

Уникальный ID. На всех рабочих станциях, вопреки заявлениям представителей фирмы «1С», он может быть одинаковым для одной и той же базы

OrderInList

Порядковый номер базы в подпапке браузера

Folder

Путь к текущей папке в браузере «1С». Для корневого каталога параметр принимает значение «/», для остальных – «/название базы»

OrderInTree

Сквозной номер базы в общей структуре

Пример подключения локальной базы:

[Тестовая локальная база]

Connect=File="С:Base";

ID=28f15724-3c41-4753-b5a4-42bb454b8be3

OrderInList=32768

Folder=/Тестовые базы

OrderInTree=65536

Пример подключения сетевой базы:

[Тестовая сетевая база]

Connect=Srvr="sql.server.domain.ru";Ref="Enterprise_test";

ID=28f15724-3c41-4753-b5a4-42bb454b8be3

OrderInList=16384

Folder=/

OrderInTree=32768

Синтаксис подкаталога

Описание каталога аналогично описанию баз, однако есть два принципиальных отличия: отсутствие параметра connect и значение параметра OrderInList=-1:

[Локальные базы]

ID=7fa1d5a9-d087-4026-9eea-f18a233d618f

OrderInList=-1

Folder=/

OrderInTree=16384

Структура файла 1Сv8strt.pfl

Анализируя создаваемый «1С» файл и изменяя различные параметры, были приобретены знания по управлению настройками визуального представления браузера «1С», умение назначать базу по умолчанию (при открытии браузера). Проанализируем фрагменты файла (листинг файла см. на сайте www.samag.ru, в разделе «Исходный код»):

{"N",1},"ShowIBsAsTree",

{"B",1},"AutoSortIBs",

{"B",0},"ShowRecentIBs",

{"B",0},"LRInfoBaseIDList",

Таблица 2. Описание параметров, управляющих конфигурацией браузера «1С»

Параметр

Описание

ShowIBsAsTree

Отображать структуру баз в виде дерева

AutoSortIBs

Выполнять автоматическую сортировку баз

ShowRecentIBs

Показать список из Х последних открытых баз. Значение параметра Х определяется пользователем «1С» в настройках браузера

LRInfoBaseIDList

Установка курсора на базу по умолчанию

Рисунок 3. Параметры настройки браузера «1С»

Рисунок 3. Параметры настройки браузера «1С»

Параметры «ShowIBsAsTree», «AutoSortIBs», «LRInfoBaseIDList» могут принимать значения 0 или 1, исключение составляет параметр «ShowRecentIBs» – принимаемые значения от 1 до 9.

Алгоритм работы скрипта

Работу скрипта условно можно разделить на несколько частей:

  1. Генерация файла 1Сv8strt.pfl
  2. Обработка данных файла v8ib.lst:
    • Чтение, анализ и вычленение данных о локальных базах.
    • Определение и формирование данных для подключения доступных сетевых баз.
    • Формирование файла v8ib.lst, создание соответствующих каталогов, файлов def.usr.

Скрипт: файл 1cv8strt.pfl

Файл 1cv8strt.pfl статичен и меняется крайне редко, поэтому существует два варианта его создания на рабочей станции пользователя: первый – копирование с сервера (см. листинг файла в приложении на сайте журнала www.samag.ru в разделе «Исходный код»), второе – его генерация с помощью сценария. Рассмотрим второй случай.

Для упрощения управления базами по умолчанию и упорядочиванию структуры рекомендуется считывать соответствующую информацию из конфигурационного файла. Пример файла приведен ниже:

[1c8]

ShowAsTree=1    

AutoSort=1      

DefaultBaseName=Сетевая база данных 1

Считывание данных из конфигурационного файла осуществляется следующим образом:

$DefaultBaseName=readprofilestring("$config_ini","1c8","DefaultBaseName")

$meta_1c8=readprofilestring("$config_ini","1c8","base1c8prefix")

$ShowAsTree=readprofilestring("$config_ini","1c8","ShowAsTree")

$AutoSort=readprofilestring("$config_ini","1c8","AutoSort")

где переменная $config_ini содержит имя и полный путь, в случае необходимости, к конфигурационному файлу. Второй параметр – название раздела, третий – соответственно параметра, значение которого возвращает функция.

Ранее описывалась структура этого файла. ID-номер базы по умолчанию определяется в двойном цикле Do…Loop и зафиксируется в переменной $default_guid.

if instr(ucase($des), ucase($DefaultBaseName))<>0

$default_guid=right( $infos[1],len( $infos[1])-3)

Endif

Перед записью в файл данные накапливаются в переменную, в данном случае $cfg. Полностью листинг генерации файла 1cv8strt.pfl приведен в приложении. В данном примере покажем лишь принцип, лежащий в основе формирования. Использование кавычек вносит коррективы в механизм генерации файла: в листинге скрипта кавычка выглядит следующим образом: « + chr(34) + ».

$en=chr(13)+chr(10)

$cfg = $cfg + "{"+$en

$cfg = $cfg + "{" + chr(34) + "LRInfoBaseIDListSize" + chr(34) + ","+$en

$cfg = $cfg + "{" + chr(34) + "N" + chr(34) + ","+ $ShowAsTree+"}," + chr(34) + "ShowIBsAsTree" + chr(34) + ","+$en

$cfg = $cfg + "{" + chr(34) + "B" + chr(34) + ","+ $AutoSort+"}," + chr(34) + "AutoSortIBs"+ chr(34) + ","+$en           

$cfg = $cfg + "}"+$en

После наполнения переменной данными осуществляется запись ее содержимого в файл. Напомним, что файл 1cv8strt.pfl находится в каталоге «Documents and Settings\%username%Application Data1C1Cv8».

$FSO = CreateObject("Scripting.FileSystemObject").GetFile($path_to_base+"1cv8strt.pfl")

if @error=0

$FSO.Delete

endif

$FSO.close

$Stream = CreateObject("ADODB.Stream")

$Stream.CharSet = "utf-8"

$Stream.Mode = 3

$Stream.Open

$Stream.WriteText($cfg)

$Stream.SaveToFile($path_to_base+"1cv8strt.pfl")

$Stream.Closeendif

Скрипт: файл v8ib.lst

Локальные базы

На первом этапе осуществляется чтение существующего файла и вычленение списка локальных баз. Пример чтения файла был приведен ранее, поэтому сразу перейдем к обработке считанных данных в переменную, например, $GetFile: после того как данные считаны, файл необходимо удалить:

$fso = CreateObject("Scripting.FileSystemObject")

$fso.DeleteFile($f_name)

$fso.close

Имеющиеся данные необходимо разбить на подстроки и записать в массив, затем, проанализировав их, вычленить локальные базы. В качестве признака, по которому будут формироваться подстроки, рекомендуется использовать символ «[». При таком преобразовании элементами массива будут содержать описания баз целиком, например:

a[0]= "[Тестовая сетевая база]" + chr(13) + chr(10) + "Connect= File = " + chr(34) + "С:\Base" + chr(34) + ";" + chr(13) + chr(10) + \

"ID=28f15724-3c41-4753-b5a4-42bb454b8be3" + chr(13) + chr(10) + "OrderInList=16384" + chr(13) + chr(10) + "" + chr(13) + chr(10) + \

"Folder=/" + chr(13) + chr(10) + "OrderInTree=32768"

Затем просмотрите и отберите элементы массива, характеризующие локальные базы. Признаком локальности базы является значение элемента connect, начинающегося с file=. Накопление данных осуществляется в переменную, которая потом также будет разложена в массив, но уже по другому признаку: переводу и возврату каретки на новую строку, а именно chr(13)+chr(10):

$en=chr(13)+chr(10)

$temp=""

' расчленение строки на элементы массива.

' Признак – наличие "["

$array_0=split($GetFile,"[")

for each $element in $array_0

' "connect=file=" – признак локальности БД

if instr(ucase($element),ucase("connect=file="))<>0

           $element="["+$element

           $temp=$temp+$element

    endif

next

$array_base=split($temp, $en)  ' массив локальных баз

Поскольку нумерация баз меняется, существующие локальные базы данных необходимо переместить в отдельную виртуальную папку, например, «Локальные базы», поэтому значения параметров OrderInList и OrderInTree необходимо обнулить, значения параметра Folder исправить на Folder=/ Локальные базы. Для этого необходимо обновить значения элементов массива:

$virtual_local_folder="Локальные базы"

for $i=0 to ubound($array_base)

$element=$array_base[$i]

    if instr(ucase($array_base[$i]),ucase("orderin"))<>0

           $array_base[$i]=left($element,instr($element,"="))

    endif

    if instr(ucase($element),ucase("folder="))<>0

           $array_base[$i]=left($element,instr($element,"=")+1)+$virtual_local_folder

    endif

next

После переприсвоения элементы массива $array_base могут иметь следующий вид:

$array_base[0]= "[Тестовая сетевая база]"

$array_base[1]= "Connect=File="С:\Base";"

$array_base[2]= "ID=28f15724-3c41-4753-b5a4-42bb454b8be3"

$array_base[3]= "OrderInList="

$array_base[4]= "Folder=/ Локальные базы"

$array_base[5]= "OrderInTree="

………………………………….

Сетевые базы

Составление списка сетевых баз основано на чтении данных из AD по следующему алгоритму: с помощью встроенной в KIX функции EnumGroup() просматривается список групп, в которые входит настоящий пользователь, и отфильтровываются только те из них, которые имеют заранее оговоренный префикс в названии, например, «1с8$_»:

$i=0

$Temp=""

Do

$Group = EnumGroup($i) 

$i = $i + 1     

If  instr(ucase($group), ucase("1c8$_"))<>0

…………..

EndIf

Until Len($Group) =0

MessageBox("$Temp","",0,0)

Рисунок 4. Группа безопасности

Рисунок 4. Группа безопасности

Поскольку название группы все время меняется, то в соединение с AD необходимо интегрировать функцию EnumGroup():

' определение имени текущено домена

$Domain = "LDAP://"+GetObject("LDAP://RootDSE").Get("defaultNamingContext")

$objConnection = CreateObject("ADODB.Connection")

$objCommand = CreateObject("ADODB.Command")

$objConnection.CommandTimeout = 120

$objConnection.Provider = "ADsDSOObject"

$objConnection.Open ("Active Directory Provider")

$objCommand.ActiveConnection = $objConnection

$i=ubound($array_base)

DO

    $Group = ENUMGROUP($p)    

    if instr("$Group","$meta_1c8")<>0

           $1c8_group=right($group,len($group)-instrrev($group,"\"))

$strADSQuery = "SELECT name,info,description FROM '" +$domain+"'  WHERE objectClass='group’ and samaccountname='"+$1c8_group+"'"

$objCommand.CommandText = $strADSQuery

    $st = $objCommand.Execute

    $st.Movefirst

Do

    $name = $St.Fields("name").Value

    $description = $St.Fields("description").Value

           $des=""

For each $element in $description

           $des=$des+$element

Next

$infos = split($St.Fields("info").Value,chr(13)+chr(10))

……………………………….

$st.MoveNext

Until $st.EOF

    endif

$p=$p+1

UNTIL Len($Group) = 0

Замечание: в приведенном примере название группы, возвращаемое функцией enumgroup() имеет вид domain\groupname, где domain – короткое имя домена. В SQL-запросе к Active Directory должно фигурировать только имя группы, т.е. необходимо отбросить префикс «domain\», поэтому короткое имя группы будет выглядеть:

$1c8_group=right($group,len($group)-instrrev($group,"\"))

Данные, содержащиеся в массиве $infos необходимо преобразовать и добавить их в конец массива $array_base. При этом добавляемые в него элементы должны соответствовать ранее описанному шаблону для сетевых баз:

$i=ubound($array_base)

DO

$array_base[$i]="["+$des+"]"

$infos = split($St.Fields("info").Value,chr(13)+chr(10))

$array_base[$i+1]= "Connect="+$infos[0]

$array_base[$i+2]= $infos[1]

$array_base[$i+3]= "OrderInList="

$array_base[$i+4]= $infos[2]

$array_base[$i+5]= "OrderInTree="

$i=$i+6

Формирование файловой структуры

Файловая структура формируется внутри каталога «Documents and Settings\%username%Application Data1C1Cv8». Расположение данного каталога на рабочей станции не фиксировано, поэтому для каждого пользователя путь необходимо определять индивидуально с помощью функции:

$path_to_base=CreateObject("WScript.Shell").SpecialFolders(5)+"\1C\1Cv8\"

Определив ID сетевой базы, в том же цикле Do..Loop (см. листинг скрипта на сайте www.samag.ru в разделе «Исходный код»), необходимо создать соответствующую базе файловую структуру.

В каталоге «Documents and Settings\%username%Application Data1C1Cv8» для каждой базы необходимо создать папку, название которой совпадает с ID этой базы, а в нем файл usr.def в кодировке UTF-8 со следующим содержанием: {«У Вас нет доступа. Обратитесь к системному администратору»}. Это сообщение будет появляться в том случае, если у пользователя нет прав доступа к данной базе данных «1С».

$id_dir_name=$path_to_base+right( $infos[1],len( $infos[1])-3)

md $id_dir_name ; создание каталога

;  создание файла def.usr

$FSO = CreateObject("Scripting.FileSystemObject").GetFile($id_dir_name+"\def.usr")

if @error=0

$FSO.Delete

endif

$FSO.close

$Stream = CreateObject("ADODB.Stream")

$Stream.CharSet = "utf-8"

$Stream.Mode = 3

$Stream.Open

$Stream.WriteText("{"+chr(34)+"У Вас нет доступа. Обратитесь к системному администратору."+chr(34)+"}")

$Stream.SaveToFile($id_dir_name+"\def.usr")

$Stream.Close

Запись данных в файл

На последнем этапе осуществляется запись сформированных данных в файл. В решении данной задачи есть несколько нюансов: помимо сформированных данных в файле необходимо в него записать информацию, касающуюся каталогов, и обновить нумерацию параметров OrderInList и OrderInTree.

Листинг описания папок для тестовых и локальных баз выглядит следующим образом:

$local_folder = "[Локальные базы]" + $en + "ID=7fa1d5a9-d087-4026-9eea-f18a233d618f" + $en + "OrderInList=-1" + $en + "Folder=/" + $en + "OrderInTree=16384"

$test_folder = "[Тестовые базы]" + $en + "ID=7fa1d5a9-d087-9636-9eea-f18a233d618f" + $en + "OrderInList=-1" + $en + "Folder=/" + $en + "OrderInTree=32768"

ID должен быть уникальным. Каким конкретно? – не известно. Был проведен эксперимент, в результате которого выяснилось, что ID может быть любым. На практике рекомендуется выбрать один из ID, созданных 1C, и изменить одну из его частей произвольным образом.

Из примера видно, что максимальное значение параметра OrderInTree=32768. Ранее отмечалось, что начало нумераций и шаг значений параметров OrderInList и OrderInTree не имеют значения. Этот факт подтвержден многочисленными экспериментами. В качестве начала отсчета были выбраны число 16384 и такой же шаг (заимствовано из «1С»). Для удобства корректировки значений введены два коэффициента $w_1 и $w_2. Один из них управляет значениями OrderInList, а второй – OrderInTree соответственно. При таком способе установки нумерации получится, что в одном из каталогов нумерация параметра OrderInList начнется с одного числа, например, 32768, а в другом – 65536. В каждом из разделов нумерация произвольна и содержимое файла будет корректно считано браузером «1С». Листинг корректировки данных следующий:

$const_w=16384

$w_1=1

$w_2=3

for each $element in $array_base

    if instr(ucase($element),ucase("orderintree"))<>0

           $s=$s+$element+cstr($const_w*$w_2)+$en

           $w_2=$w_2+1

    else

           if instr(ucase($element),

                 ucase("orderinlist"))<>0

                 $s=$s+$element+cstr

                        ($const_w*$w_1)+$en

                 $w_1=$w_1+1

           else

           $s=$s+$element+$en

           endif

    endif

next

После того как все данные к записи приготовлены, можно приступить к записи в файл. В него следует записать содержание трех переменных: две переменные содержат информацию о создаваемых каталогах в браузере «1С», третья – накопленные элементы массива $array_base (переменная s). Напомню, что файл v8ib.lst находится в каталоге «Documents and Settings\%username%Application Data1C1Cv8».

$en=chr(13)+chr(10)

$Stream = CreateObject("ADODB.Stream")

$Stream.CharSet = "utf-8"

$Stream.Mode = 3

$Stream.Open

$Stream.WriteText($local_folder+$en+$test_folder+$en+$s)

$Stream.SaveToFile($path_to_base+"v8ib.lst")

$Stream.Close

Таким образом, мы создали компонент сценария регистрации пользователей в сети, который позволил нам в автоматическом режиме управлять подключением сетевых баз данных, при этом локальные базы остаются неприкосновенными. Также выполняется сортировка существующего списка по локальным, сетевым и тестовым базам.

Литература:

  1. Коробко И. Автоматизация процесса подключения баз «1С» с помощью сценария регистрации пользователей в сети. – Журнал «Системный администратор» №3, 2005 г. – 48-51 с (http://www.samag.ru/cgi-bin/go.pl?q=articles;n=03.2005;a=01).

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-41
Fax: (499) 277-12-45
E-mail: sa@samag.ru