Предыстория: В связи с тем что производилась замена железа на сервере. Было установлено всё с нуля и произвели восстановление базы LERS. Первой проблемой стало что новый LERS не принял старую базу (как узнать какая версия базы и где взять под неё именно нужный дистрибутив непонятно). После небольших манипуляций (установил, удалил, скопировал и т.п. при поддержке сотрудников LERS мы смогли всё привязать). После этого появилась следующая проблема: нами был написан алгоритм в PowerShell для выгрузки данных в Excel файл.
########################################################################
# Настройки
########################################################################
# путь к фреймворку ЛЭРС УЧЕТ
$LersFrameworkPath = 'c:Program FilesLERSCommonLers.System.dll'
# Адрес сервера приложения
$ServerAddress = 'localhost'
# Порт сервера приложения
$ServerPort = 10000
# Имя входа/пароль для подключения к Серверу
$Login = 'admin'
$PassWord = 'admin'
# Отчетный день месяца
$Dayot = 19
$Monty = @{}
$Monty = @( "000" ; "Январь"; "Февраль"; "Март"; "Апрель"; "Май"; "Июнь"; "Июль"; "Август"; "Сентябрь"; "Октябрь"; "Ноябрь"; "Декабрь" );
# параметры выгрузки
$valS = -1
$valF = -1
$valQ = -1
$valS2 = -1
$valF2 = -1
$valQ2 = -1
$dtS = [datetime]::Today
$dtF = [datetime]::Today
# Параметры файла Ecel
$HouseOwner = "ОАО `"АИЖК`" по"
$ExFile = 'C:LERS-ExportTRIC.xlsx'
$ExSheet = 1
$SRow = 8
$SCol = 1
$nick_GP = '58519823' # ГП-1
##################################################################
# Подключаемые типы
##################################################################
try {
# подключаем фреймворк
add-type -path $LersFrameworkPath
}
catch {
try
{
# подключаем фреймворк
update-typedata
#-path ($LersFrameworkPath);
#[System.reflection.Assembly]::LoadFile($LersFrameworkPath);
}
catch
{
write-host 'Ошибка. Не удалось загрузить файл Lers.System.dll. Проверьте правильность расположения файла. ' + $Error[0].Exception.Message
exit
}
}
########################################################################
# Функции
########################################################################
# Проверяет заданы ли параметры настройки скрипта
Function CheckParameters($ServerAddress, $ServerPort, $Login, $PassWord) {
try
{
if ($ServerAddress -eq '');
{
throw new-object Exception('Адрес сервера ЛЭРС УЧЕТ не задан.');
}
if (($ServerPort -eq $null) -or ($ServerPort -eq 0) -or ($ServerPort -eq ''));
{
throw new-object Exception('Порт сервера ЛЭРС УЧЕТ не задан.');
}
if ($Login -eq '');
{
throw new-object Exception('Имя входа в ЛЭРС УЧЕТ не задано.');
}
if ($PassWord -eq '');
{
throw new-object Exception('Пароль для входа в ЛЭРС УЧЕТ не задан.');
}
if ($ExFile -eq '');
{
throw new-object Exception('No excell file found.');
}
}
catch
{
throw new-object Exception('Параметры скрипта не настроены. ', $Error[0].Exception);
}
}
##################################################################
# возвращает описание исключений
Function GetFullExceptionMessage([Exception]$exc) {
if($exc -eq $null);
{
return ''
}
$msg = $exc.Message
if ($exc.InnerException -ne $null);
{
$mes = GetFullExceptionMessage $exc.InnerException
$msg = $msg + ' ' + $mes
}
return $msg
}
##########################################################################
# Функция подключается к серверу автоматизации и возвращает объект сервера
Function ConnectToServer() {
try
{
Write-Host 'подключаемся к серверу по адресу ' $ServerAddress ':' $ServerPort
$securePassword = [Lers.Networking.SecureStringHelper]::ConvertToSecureString($PassWord);
$authenticationInfo = New-Object Lers.Networking.BasicAuthenticationInfo($Login, $securePassword);
# подключаемся к серверу
$server = new-object Lers.LersServer
$server.Connect($ServerAddress, $ServerPort, $authenticationInfo);
return $server
}
catch
{
throw new-object Exception('Не удалось подключится к серверу ЛЭРС УЧЕТ. ', $Error[0].Exception);
}
}
##########################################################################
# Точка входа
##########################################################################
try
{
Clear-Host
Write-Host 'Запуск экспорта данных по дому.'
try {
$dtS = [DateTime]::Today
$ddif = $Dayot - $dtS.Day
if ($dtS.Day -Le $Dayot) {
$dtF = $dtS.AddDays($ddif)
$dtF = $dtF.AddMonths(-1);
$dtS = $dtF.AddMonths(-1);
} else {
$dtF = $dtS.AddDays($ddif);
$dtS = $dtF.AddMonths(-1);
}
}
catch {
throw new-object Exception('Период выгрузки не определен. ', $Error[0].Exception);
exit
}
Write-Host ("Период выгрузки с ", $dtS.ToString(), " по ", $dtF.ToString());
# проверяем параметры настройки скрипта
CheckParameters $ServerAddress $ServerPort $Login $PassWord
write-host 'Подключаемся к серверу ЛЭРС.'
# подключаемся к серверу ЛЭРС
$server = ConnectToServer
# загрузка владельцев
Get-Content "C:LERS-ExportFIO.txt" | Out-File -Encoding UTF8 "C:LERS-ExportFIO1.txt"
$preO = [io.file]::ReadAllText("C:LERS-ExportFIO1.txt")
$OwnerList = ConvertFrom-StringData -StringData $preO
# Подключаемся к файлу эксель
$xl = New-Object -COM "Excel.Application"
$xl.Visible = $true
$wb = $xl.Workbooks.Open($ExFile);
$ws = $wb.Sheets.Item($ExSheet);
$ws.Cells.Item( 4 , 1 ) = "за " + $Monty[$dtF.Month.ToString()] + " " + $dtF.Year.ToString() + " г."
#write-host 'Запрос данных сервера ЛЭРС.'
try {
$HPoints = @{}
$Rooms = @{}
$Rooms=$server.Rooms
$house=$server.Communal.GetHouseById(1) # Дом тоже приходится искать перебором
#Write-Host $house, $Rooms
#$Rooms=$house.Rooms
$addr1=$house.Comment
Write-Host $addr1
$Addr = $addr1 -split ","
}
catch {
write-host 'error - No point ahieved - ' (GetFullExceptionMessage $Error[0].Exception);
exit
}
Write-Host ("Cохраняем данные от сервера ЛЭРС УЧЕТ ");
Write-Host $Rooms
$iRoom=1177 #Пришлось добавить обычно тут была единица
$LRoom=2234 # Число с большой вероятностью после всех помещений
$RF = $true # флаг контроля цикла
$iRow = $SRow
While ($iRoom -le $LRoom) { #($RF -eq $true) { #ранний вариант предполагал закончить цикл на первой пустой записи
try { $R1 = $Rooms.GetById(($iRoom), [Lers.Communal.RoomInfoFlags]::Counters )
$RF = $true
}
catch {
$RF = $false
Write-Host "пропущен номер ", $iRoom
}
#write-host $Rooms, $R1, $RF
if ($RF -eq $true) {
$HPoints = $server.MeasurePoints.GetListByRoom($R1.Id)
Write-Host ("Cохраняем данные квартиры ", $R1.Id, $R1.Title);
[Lers.Communal.CommunalMeasurePoint]$Point = $null
# Подготовка таблицы данных
if ($OwnerList.Contains($R1.Title.ToString()) -eq $true) { # Проверка и поиск ФИО в списке
$RooNa= $OwnerList[$R1.Title.ToString()]
} else { $RooNa = $HouseOwner }
try {
foreach ($HPo in $HPoints) {
$valS = 0; $valF = 0; $valQ = 0; $valS2 = 0; $valF2 = 0; $valQ2 = 0
$Point = $HPo
$Dhp = $HPo.Data.GetTotals($dtS, $dtF);
$valS = -1 ; $valS2 = -1
if ($Dhp -ne $null) {
$DFF= $Dhp.Find($dtF) #[[Convert]::ToInt32(($Dhp.Count-1))]
$DFS= $Dhp.Find($dtS);
$DhpSF = @( $DFS ; $DFF );
foreach ( $Dhpd in $DhpSF) {
#write-host $Dhpd
if ($Dhpd.DateTime -ne $null) {
if ($Dhpd.ResourceKind -eq [Lers.Data.ResourceKind]::Water) {
if ($valS -eq -1) { $valS = $Dhpd.V_in }
$valF = $Dhpd.V_in
#$valQ = $valF - $valS
}
if ($Dhpd.ResourceKind -eq [Lers.Data.ResourceKind]::Electricity) {
if ($valS -eq -1) { $valS = $Dhpd.Ap1; $valS2 = $Dhpd.Ap2 }
$valF = $Dhpd.Ap1 ; $valF2 = $Dhpd.Ap2
#$valQ = $valF - $valS ; $valQ2 = $valF2 - $valS2
}
$valD = $Dhpd.DateTime
# Write-Host $Dhpd.DateTime, $valF, $valF2, $valQ, $valQ2 ,$Dhpd.ResourceKind
}
}
$valQ = $valF - $valS
$valQ2 = $valF2 - $valS2
#Write-Host $valD, $valF, $valF2, $valQ, $valQ2
}
else {
$valD = $dts; $valF = 0; $valF2 = 0; $valQ = 0; $valQ2 = 0;
}
$ws.Cells.Item($iRow, $SCol) = $R1.PersonalAccountNumber
$ws.Cells.Item($iRow, $SCol + 1) = $nick_GP
$ws.Cells.Item($iRow, $SCol + 2) = $Addr[0]
$ws.Cells.Item($iRow, $SCol + 3) = $Addr[1]
$ws.Cells.Item($iRow, $SCol + 4) = $Addr[2]
$ws.Cells.Item($iRow, $SCol + 5) = $Addr[3]
$ws.Cells.Item($iRow, $SCol + 6) = $R1.Title
$ws.Cells.Item($iRow, $sCol + 9) = $RooNa
$ws.Cells.Item($iRow, $SCol +10) = $R1.Area
$res = $HPo.Refresh([Lers.Core.MeasurePointInfoFlags]::Counter);
$DevP =$HPo.Counter.SerialNumber
$res = $HPo.Refresh([Lers.Core.MeasurePointInfoFlags]::Device);
if ( $HPo.SystemType -eq [Lers.Core.SystemType]::Electricity) {
$ws.Cells.Item($iRow, $SCol +11) = "383"
$ws.Cells.Item($iRow, $SCol +12) = "Электроэнергия (день)"
$ws.Cells.Item($iRow, $SCol +13) = $HPo.Device.SerialNumber
$ws.Cells.Item($iRow, $SCol +14) = $HPo.Title
$ws.Cells.Item($iRow, $SCol +15) = $dtF.Date #ToString();
$ws.Cells.Item($iRow, $SCol +16) = ('{0:F3}' -f $valS);
$ws.Cells.Item($iRow, $SCol +17) = ('{0:F3}' -f $valF);
$ws.Cells.Item($iRow, $SCol +18) = ('{0:F3}' -f $valQ);
$iRow = $iRow + 1
$ws.Cells.Item($iRow, $SCol) = $R1.PersonalAccountNumber
$ws.Cells.Item($iRow, $SCol + 1) = $nick_GP
$ws.Cells.Item($iRow, $SCol + 2) = $Addr[0]
$ws.Cells.Item($iRow, $SCol + 3) = $Addr[1]
$ws.Cells.Item($iRow, $SCol + 4) = $Addr[2]
$ws.Cells.Item($iRow, $SCol + 5) = $Addr[3]
$ws.Cells.Item($iRow, $SCol + 6) = $R1.Title
$ws.Cells.Item($iRow, $sCol + 9) = $RooNa
$ws.Cells.Item($iRow, $SCol +10) = $R1.Area
$ws.Cells.Item($iRow, $SCol +11) = "384"
$ws.Cells.Item($iRow, $SCol +12) = "Электроэнергия (ночь)"
$ws.Cells.Item($iRow, $SCol +13) = $HPo.Device.SerialNumber
$ws.Cells.Item($iRow, $SCol +14) = $HPo.Title
$ws.Cells.Item($iRow, $SCol +15) = $dtF.Date
$ws.Cells.Item($iRow, $SCol +16) = ('{0:F3}' -f $valS2);
$ws.Cells.Item($iRow, $SCol +17) = ('{0:F3}' -f $valF2);
$ws.Cells.Item($iRow, $SCol +18) = ('{0:F3}' -f $valQ2);
}
if ( $HPo.SystemType -eq [Lers.Core.SystemType]::ColdWater) {
$ws.Cells.Item($iRow, $SCol +11) = "10"
$ws.Cells.Item($iRow, $SCol +12) = "Холодное водоснабжение"
$ws.Cells.Item($iRow, $SCol +13) = $DevP
$ws.Cells.Item($iRow, $SCol +14) = $HPo.Title
$ws.Cells.Item($iRow, $SCol +15) = $dtF.Date
$ws.Cells.Item($iRow, $SCol +16) = ('{0:F3}' -f $valS);
$ws.Cells.Item($iRow, $SCol +17) = ('{0:F3}' -f $valF);
$ws.Cells.Item($iRow, $SCol +18) = ('{0:F3}' -f $valQ);
}
if ( $HPo.SystemType -eq [Lers.Core.SystemType]::HotWater) {
$ws.Cells.Item($iRow, $SCol +11) = "8"
$ws.Cells.Item($iRow, $SCol +12) = "Горячее водоснабжение"
$ws.Cells.Item($iRow, $SCol +13) = $DevP
$ws.Cells.Item($iRow, $SCol +14) = $HPo.Title
$ws.Cells.Item($iRow, $SCol +15) = $dtF.Date
$ws.Cells.Item($iRow, $SCol +16) = ('{0:F3}' -f $valS);
$ws.Cells.Item($iRow, $SCol +17) = ('{0:F3}' -f $valF);
$ws.Cells.Item($iRow, $SCol +18) = ('{0:F3}' -f $valQ);
}
$iRow = $iRow + 1
}
}
catch {
throw new-object Exception('Не удалось выгрузить данные по точкам учета ', $Error[0].Exception);
exit
}
}
$iRoom = $iRoom + 1
}
Write-Host 'Экспорт данных завершен.'
}
catch {
write-host 'Ошибка экспорта данных!!! ' (GetFullExceptionMessage $Error[0].Exception);
exit
}
# Осводбождение объекта эксель
$wb.Save();
$wb.Close();
$xl.Quit();
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl);
########################################################################
Код успешно был опробован на трёх серверах, на этом же возникла нижеследующая проблема:
При запросе данных помещения через RoomManager для записей с 1 по 1177 возвращается пустое значение (нет объекта), с 1178 по 1808 есть записи.
При просмотре через программу LERS все помещения на месте (а именно с 1 по 630 квартиру). Печально очень то, что нельзя узнать идентификаторы существующих квартир никаким способом кроме как перебором. Такая же картина наблюдается и с домом (функция GetById).
При выборе помещений через RoomCollection(server.house.rooms) хотелось бы получать массив не содержащий пустых записей.
Просим внести изменение в вашу библиотеку FrameWork, либо подсказать более оптимальный алгоритм выбора данных по помещениям в требуемом доме.