{lang: 'ru'}
Системная интеграция

Программистам



Компания «АЗСофт» имеет многолетний опыт использования недурных инструментов типа Sybase Powerbuilder, ERwin, Crystal Reports, а также опыт работы с Oracle Database.На этой странице мы выражаем добрые чувства к коллегам и публикуем на наш взгляд интересные и забавные штучки, то, что называют tricks & tips, полезные ссылки, etc.

Сейчас опубликовано:

1. Пример кода на Powerbuilder для вызова Crystal Reports engine(API)

2. Пример кода на Powerbuilder для переконфигурирования источника ODBC

3. Для Powerbuilder - несерьезные "примочки"

4. Пример построения дерева на Power Builder

5. Забавная ситуация (мелочи жизни)

6. Пример использования UNION во VIEW для Oracle

7. Оцените Oracle Enterprise Manager

8. Конфигурирование Microsoft ISA 2004

9. Oracle HTML DB (WEB - приложение)

10. Oracle HTML DB APEX - техника COLLECTIONS

 

В примерах опущены объявления переменных и внешних функций, если нужны комментарии, пишите info@azsoft.ru

 


 

Пример кода на Powerbuilder для вызова Crystal Reports engine(API)

//*****************************************************

// Начало - проверки и указание файла отчета

//*****************************************************
engineopen = PEOpenEngine ()

if engineopen <> 0 then
// messagebox ("Прекрасно!", "Запустили Engine!")
else
messagebox ("Погано...", "Стартер отказал!")
end if
 

reportfilename = 'Оплата клиентов.rpt'
 

if engineopen <> 0 then
job = PEOpenPrintJob(reportfilename)
      if job = 0 then
         messagebox ("Паршиво", "Нет отчета")
      else
         // messagebox ("Хорошо", "Отчет засосало")
      end if
else
messagebox ("Все же погано", "Стартер отказал")
end if

//******************************************************

// Ниже заполнение структурки для Logon, так изгаляться приходится

//  из-за bug в Паше

//******************************************************

long cpos,strlng

li.size = 514

strlng = len(DataSourceName)
for cpos = 1 to strlng
li.servername[cpos] = mid(DataSourceName,cpos,1)
next

strlng = len(databasename)
for cpos = 1 to strlng
li.databasename[cpos] = mid(databasename,cpos,1)
next

strlng = len(userid)
for cpos = 1 to strlng
li.userid[cpos] = mid(userid,cpos,1)
next

strlng = len(userpwd)
for cpos = 1 to strlng
li.password[cpos] = mid(userpwd,cpos,1)
next

rcode = PESetNthTableLogonInfo( job, 0, li, TRUE);

if rcode = 0 then
messagebox ("", "Ошибка при выполнении PESetNthTableLogonInfo для DSN [" + li.servername + "] !" );
end if

 

//**************************************************

// Ниже подмена формул в отчете - Selection Formula и простых

//**************************************************
rsformula='({OP_ACCOUNT.ACCOUNT_NUM} = 62.00 or {OP_ACCOUNT.ACCOUNT_NUM} = 63.00 or '+&
' {OP_ACCOUNT.ACCOUNT_NUM} = 64.00) and '+&
'({OP_ACCOUNT_1.OPERATION_TYPE} like "*плата*" ) and '+&
'{OP_ACCOUNT_1.OP_DATE} >= Date('+string(year(date(datest)))+","+ &
string(month(date(datest)))+','+string(day(date(datest)))+') and '+&
'{OP_ACCOUNT_1.OP_DATE} <= Date('+string(year(date(dateend)))+","+ &
string(month(date(dateend)))+','+string(day(date(dateend)))+')'

rcode=PESetSelectionFormula(job,rsformula)
if rcode = 0 then
messagebox("Беда", "Selection Formula NOT Set")
else
// messagebox("Беда", rsformula)
end if
//............................................................................................

rcode=PESetFormula (job, "Дата начала", '"'+string(datest)+'"')

if rcode = 0 then
messagebox("Беда", "Данные не подменились")
else
end if

rcode=PESetFormula (job, "Дата конца", '"'+string(dateend)+'"')

if rcode = 0 then
messagebox("Беда", "Данные не подменились")
else
end if

//............................................................................................
// Ну и пора выводить на экран

//


if job <> 0 then
rcode = PEOutputToWindow(job, "Отчет", 0, 0, 790, 590, 0, 0)
if rcode = 1 then
outputset = 1
else
messagebox ("Беда", "OutputToWindow Not Set")
end if
else
messagebox ("Беда", "Not Print Job Opened")
end if

lc.StructSize=514
lc.hasGroupTree=1
lc.canDrillDown=1
lc.hasNavigationControls=1
lc.hasCancelButton=1
lc.hasPrintButton=1
lc.hasExportButton=1
lc.hasZoomControl=1
lc.hasCloseButton=1
lc.hasProgressControls=1
lc.hasSearchButton=1
lc.hasPrintSetupButton=1
lc.hasRefreshButton=1

PESetWindowOptions (job, lc)

if rcode = 1 then
else
messagebox ("Беда", "OutputToWindowOptions Not Set")
end if

//long hWnd

//PrinterSetup (hWnd)
//..............................................................................................

// А здесь вытаскиваем детальную информацию, если была ошибка

//
if engineopen <> 0 then

       if outputset = 1 then
             if job <> 0 then
             rcode = PEStartPrintJob (job, True)
                if rcode = 1 then
                else
                      errcode = PEGetErrorCode(job)
                      messagebox("Ошибка запуска отчета", "Error Starting Print Job")
                      messagebox("Код ошибки Crystal Reports", errcode)

                      rcode = PEGetErrorText( job, texthandle, textLength )
                      rcode = PEGetHandleString( textHandle, errorText, textLength )

                      messagebox("Детализация ошибки", errortext)

               end if
            else
               messagebox("Message", "No Job Open to Start")
            end if
         else
           messagebox("Message", "First Select a Print Destination")
         end if

else
messagebox ("Information!", "Please open the engine before calling this function.")
end if

PEClosePrintJob(job)

 

 

Пример кода на Powerbuilder для переконфигурирования источника ODBC

//******************************************************

// Здесь маленькая фишка - засунуть NULL в строку DBPARM

// (Привет Игорю!)
//******************************************************

char NullChar='@',IndeedNullChar

whwnd=0
string String1,String2
odbc_driver=ProfileString("app.INI","DBCash","ODBCDrv","")

odbc_dsn = 'DSN='+ProfileString("app.INI","DBCash","DSN","")
odbc_db = 'DB=' + ProfileString("app.INI","DBCash","Database","")
ODBC_CONFIG_DSN=2
dbparm=fill('_',200)


SetNull(IndeedNullChar)
String1='DSN='+DataSourceName
String2=ProfileString("app.INI","DBCash","ODBCDBParam","")+'='+DataBaseName
DBParm=String1+NullChar+String2+NullChar+NullChar
DBParmLen=Len(DBParm)

FOR Position=1 TO DBParmLen
IF DBParm[Position]=NullChar THEN
DBParm[Position]=IndeedNullChar
END IF
NEXT


if not SQLConfigDataSource(whwnd, ODBC_CONFIG_DSN, odbc_driver, DBParm) then
messagebox("ODBC", "Неудача")
else
end if
 

 

Для Powerbuilder - несерьезные "примочки"

//*****************************************

// Проиграть музыку

//*****************************************

uint lui_NumDevs

lui_NumDevs = WaveOutGetNumDevs()
IF lui_NumDevs > 0 THEN
sndPlaySoundA( "sound.wav", 1 )
END IF

 

 

Пример построения дерева на PowerBuilder.

 

Пример 1. Обычное (не рекурсивное) дерево

 

Исходные данные: Таблица «COMMODITY» - номенклатуры товара с произвольным, но заранее заданным количеством типов N. Поля: «TYPE1», «TYPE2», …, «TYPEN».

 

Задача: Построить дерево групп товаров с иерархией, соответствующей типам.

 

Используемые объекты: Элемент TreeViewItem.

 

Решение:

 

Функция создания дерева:

 

SetPointer(HourGlass!)

 

Long    ll_Root

TreeViewItem  ltvi_Root

 

// К количеству уровней добавляем единицу для корневого уровня

il_maxlevel = il_maxlevel + 1

 

// Добавляем корневой элемент

ltvi_Root.Label = "Дерево товаров" // Видимая метка

ltvi_Root.PictureIndex = 1 // Индекс картинки (делается при создании объекта)

ltvi_Root.SelectedPictureIndex = 1 // Индекс картинки при выборе элемента (тот же)

ltvi_Root.Children = True // Наличие подэлементов

ll_Root = tv_1.InsertItemLast(0, ltvi_Root) // Добавление элемента

 

// Добавляем корневой элемент

tv_1.ExpandItem(ll_Root) // Раскрываем содержимое первого уровня

tv_1.SelectItem(ll_Root) // Выбираем корневой элемент

 

Скрипт на событие ItemPopulate (первое раскрытие элемента) дерева:

 

string    ls_select_cursor, ls_current_data, ls_err

long ll_errcode, ll_current

Integer li_Rows, li_Level, li_Cnt

TreeViewItem ltvi_Current, ltvi_base, ltvi_New

 

SetPointer(HourGlass!)

 

// Определяем уровень

GetItem(handle, ltvi_Current)

GetItem(handle, ltvi_base)

ll_current = handle

li_Level = ltvi_Current.Level

 

// Строим строку запроса для курсора

ls_select_cursor = 'SELECT DISTINCT TYPE' + string(li_level) +&

            ' FROM "COMMODITY"'

 

if li_level > 1 then // Надо составить условие для всех родителей

 

            ls_select_cursor = ls_select_cursor + ' WHERE '

 

            // Идем по уровням вверх до последнего

            FOR li_cnt = li_level - 1 TO 1 STEP -1

                       

                        ls_select_cursor = ls_select_cursor + '"COMMODITY"."TYPE' +&

                                   string(li_cnt) + '" = ' + "'" + string(ltvi_current.data) + "'"

                       

                        if li_cnt <> 1 then ls_select_cursor = ls_select_cursor + ' AND '

                       

                        ll_current = FindItem(ParentTreeItem!, ll_current) // Находим родителя

                        GetItem(ll_current, ltvi_current)

                       

            NEXT

 

end if

 

ls_select_cursor = ls_select_cursor + ' ORDER BY TYPE' + string(li_level)

 

// Объявляем курсор и идем по нему (проверка на ошибки для краткости будет опущена)

DECLARE lcur_select DYNAMIC CURSOR FOR SQLSA;

PREPARE SQLSA FROM :ls_select_cursor USING SQL_UO;

OPEN DYNAMIC lcur_select;

 

FETCH lcur_select into :ls_current_data;

           

DO WHILE sql_uo.sqlcode <> 100

 

            ltvi_New.Label = ls_current_data // Видимое на экране обозначение

            ltvi_New.Data = ls_current_data // Данныете же

 

            if isnull(ltvi_new.data) then

            else

 

                        ltvi_New.PictureIndex = 2 // Номера картинок

                        ltvi_New.SelectedPictureIndex = 3

 

                        // Если уровень предельный, то детей быть не может

                        If li_Level < il_maxlevel - 1 Then

                                   ltvi_New.Children = True

                        Else

                                   ltvi_New.Children = False

                        End If

           

                        // Добавляем найденный элемент в конец

                        If tv_1.InsertItemLast(handle, ltvi_New) < 1 Then

                                   MessageBox("Error", "Error inserting item", Exclamation!)

                        End If

 

            end if

           

LOOP

 

CLOSE lcur_select;

 

Результат:

 

 

 

Забавная ситуация (мелочи жизни)

Буду рад, если кто-нибудь предложит более правильное решение данной проблемы.

При усовершенствовании программного модуля «Счетчик купюр», столкнулся со следующими трудностями.

При нажатии клавиши «Enter» в одном из полей дополнительной колонки, количество купюр должно приплюсоваться к базовой, а само значение этой колонки обнулиться.

Проблема 1. Отслеживание нажатия клавиши “Enter

Решается просто:

Событие key() для окна:

if key = KeyEnter! then

….

end if

 

Проблема 2. В каком из полей находится сейчас фокус (или был в последний раз в одном из интересующих нас полей). Такой функции ни для окна, ни для объекта edit mask я не нашел. Пришлось выкручиваться следующим образом:

 

1. Для события getfocus() каждой из edit_mask_control нужного столбца записываем:

 

ii_focus_plus = 13 ( где 13 – номер соответствующего объекта)

 

2. В упомянутом уже событии key() для окна:

 

if key = KeyEnter! then

 

            CHOOSE CASE ii_focus_plus

                        CASE 13

                                   em_1.text = string( long(em_13.text) + long(em_1.text) )

                                   em_13.text = '0'

                        CASE 14

                                   em_2.text = string( long(em_14.text) + long(em_2.text) )

                                   em_14.text = '0'

                        …

                        CASE 24

                                   em_12.text = string( long(em_24.text) + long(em_12.text) )

                                   em_24.text = '0'

                        CASE ELSE

                                   // Ничего не делаем

            END CHOOSE

end if

 

Такие дела…

 

 

 

(продолжение следует)

 

Господа, позволим себе обратить Ваше внимание на Seagate Crystal Reports 8: The Complete Reference.Джордж Пек (2001)неплохую книжку, продаваемую в Озоне по Crystal Reports  

 

 

Главная | ERP NOVA | ERP NOVA - автоматизация производства | ERP NOVA - управление закупками | ERP NOVA - для управления малым бизнесом | CRM NOVA - управление взаимоотношениями с клиентами | Цены | Продукты | СДО АЗСофт | Описание СДО АЗСофт | Учебные курсы | Услуги дистанционного обучения | Услуги | ПО от АЗСофт | Компьютеры от АЗСофт | Статьи | Программистам | Компания | Новости | Фото | Клиенты | Контакты |