Первые шаги по OLAP

Программирование на Атлантисе (VIP, FCOM, ARD), FastReport

Модераторы: m0p3e, edward_K, Модераторы

Ответить
Zver
Местный житель
Сообщения: 204
Зарегистрирован: 13 ноя 2012, 12:47
Откуда: СПб
Контактная информация:

Первые шаги по OLAP

Сообщение Zver »

Уважаемые форумчане,
Очень понравилась презентация по OLAP, сейчас пытаюсь что-либо попробовать.
Начал с самого, как кажется на первый взгляд, варианта - построить куб на основании данных в Browse.

Browse строится по таблице в памяти. Логика такова - данные для собираются в таблицу MTFORREPORT,
а затем выводятся либо в файл, либо на экран. Хочу уменьшить время на написание оформления отчета с помощью OLAP. Броуз отображается в отдельном окне.

После нажатия кнопки построения OLAP-куба появляется сообщение:

Код: Выделить всё

System.Data.DuplicateNameException: Столбец с именем "MTFORREPORTDKOL_RES" уже принадлежит этому DataTable.
   в System.Data.DataColumnCollection.RegisterColumnName(String name, DataColumn column)
   в System.Data.DataColumnCollection.BaseAdd(DataColumn column)
   в System.Data.DataColumnCollection.AddAt(Int32 index, DataColumn column)
   в AtlOlap.frmOlap.CreateBrowseTables()
   в AtlOlap.frmOlap.InitDataSet()
   в AtlOlap.frmOlap.OpenCube()
   в AtlOlap.frmOlap..ctor(d_getFieldCount _getFieldCount, d_getFieldName _getFieldName, d_getFieldType _getFieldType, d_getFieldRead _getFieldRead, d_getFieldValue _getFieldValue, d_getValueNaT _getValueNaT, d_getOneValue _getOneValue)
После закрытия сообщения окно, в котором находится броуз, закрыть не получается.
Как с этим бороться и что это может значить?
MTFORREPORT - это название таблицы в памяти.
Программист-самоучка
aks
Сообщения: 7
Зарегистрирован: 17 июл 2013, 13:54

Re: Первые шаги по OLAP

Сообщение aks »

День добрый.
Была попытка вставить в таблицу поля с именем которое в ней уже есть. Окно не закрывается, потому что не обработалась данная ошибка и не закрылась визуализация.
Если не сложно скажите версию Атлантис на которой работаете и выложите примерчик(хотя бы важные куски: описание таблицы, как выглядит логическая таблица...), чтоб можно было получить такой же результат. это значительно ускорит процесс поиска причины, исправления ошибки и поиска варианта чтобы все же получить отчет.
Zver
Местный житель
Сообщения: 204
Зарегистрирован: 13 ноя 2012, 12:47
Откуда: СПб
Контактная информация:

Re: Первые шаги по OLAP

Сообщение Zver »

Код интерфейса приведён ниже.

С точки зрения построения OLAP, суть его сводится к тому,
что заполняется таблица mtForReport, которая отображается в отдельном окне wnRasprReserv.

Хотелось бы из этого окна иметь возможность построения куба.

Сейчас используем Атлантис 5.4.41 ( на выходных планируем переход на 5.4.44).

Код: Выделить всё

#include ObjReservHelper.vih
#include marker.vih
#include BranchHelper.vih
#include Query.vih
#include UserHelper.vih

interface Release_Reserv_Zakaz_Report;
  show at (,,, 25)

#define IsTestMode

const
  START_ROW: integer = 1;
  MC_COL: integer = 1;
  ORDER_COL: integer = 4;
  REQUARED_COL: integer = 5;
  RELEASED_COL: integer = 6;
  AGREED_COL: integer = 7;
  RESERVED_COL: integer = 8;
  FREE_OST_KOL: integer = 9;
  RESERVED_OTHER_KOL: integer = 10;
  MNPLAN_STATUS_KOL: integer = 11;

  OSN_ZAK_WAY: comp = 4611706311621891942;
  VP_WAY: comp = 281474976710889;

  REQUARED: word = 1;
  RELEASED: word = 2;
  AGREED: word = 4;
  RESERVED: word = 0;

  //Логи
  LOG_FOLDER       : string = 'd:\Logs\Release_Reserv\';
  RESULT_TABLE_LOG : string = LOG_FOLDER + 'ResultTable.txt';
  FOR_REPORT_LOG   : string = LOG_FOLDER + 'ForReport.txt';
  PROFILER_LOG     : string = LOG_FOLDER + 'Profiler.txt';
  RASPRED_LOG      : string = LOG_FOLDER + 'Raspred.txt';

end;

var
  pi_ReservHelper : ReservHelPer new;

  sFile: string;
  iCurRow: integer;
  TotalReserv: double;
  TotalOst: double;
  Filials: longInt;
  tTmp: time;
  iMnPlan: integer;
  wSelecSub: integer;
  flMC_List: string;
  flMC_Indent: string;
  flTypeSelMC: integer;
  flTypeRep: integer;

table struct mtClaim_Mc
(
  cMc: comp
  , cMnPlan: comp
  , Kol: double
)
with index
(
  ind01 = cMnplan
);

table struct mtValSpMnP_Kol
(
  cMnPlan: comp
  , cMc: comp
  , Kol: double
)
with index
(
  ind01 = cMnPlan
  , ind02 = cMnPlan + cMc
);

table struct ResultTable
(
  cMc: comp
  , cMnPlan: comp
  , dKol: double
  , wType: word
)
with index
(
  ind01 = cMc
 , ind02 = cMnPlan
 , ind03 = cMc + cMnplan
);

table struct mtForReport
(
  cMc: comp
  , cMnPlan: comp
  , dKol_Req: double
  , dKol_Rel: double
  , dKol_Agr: double
  , dKol_Res: double
  , dKol_NotRsvd : double
  , dKol_DoReserv: double
)
with index
(
  ind01 = cMc
  , ind02 = cMnPlan
  , ind03 = cMc + cMnPlan
);

table struct mtMnPlan_Selected
(
   Num: integer
  , cMnPlan: comp
  , Number: string
  , Name: string
)
with index
(
  ind01 = Num
  , ind02 = cMnPlan
);

table struct mtMC_List
(
  cKatSopr: comp
  , Npp: word
  , cMc: comp
  , MC_Name: string
  , MC_Obozn: string
  , MC_BarKod: string
  , dKol: double //Пришло по позиции
  , dSkl: double //количество на складах
)
with index
(
  ind01 = cMc
);

table struct mtSaldoRaz
(
  nRec    : comp
  ,cmc    : comp
  ,cMnPlan: comp
)
with index
(
  ind01 = cMc + cMnPlan
  ,ind02 = cMnPlan
);

table struct mtSpMnplan
(
  nRec    : comp
  ,cIzd   : comp
  ,cMnplan: comp
)
with index
(
  ind01 = cIzd + cMnPlan
);

create view
var
  vw_cMc        : comp;
  vw_PrMc       : word;
  vw_MnPlanNrec : comp;
  vw_iPrMc      : integer;
  vw_Filial_name: string;
  vw_cKatSopr   : comp;
  vw_cSpMnPlan  : comp;
  vw_cSklad     : comp;

select
  KatMc.barkod
  (fieldname = flMcBarkod)
  , KAtMc.Nrec
  (fieldname = flMCNrec)
  , KatMc.Obozn
  (fieldname = flMcObozn)
  , katMc.name
  (fieldname = flMcName)

  ,MnPlan_All.Number
  (fieldname = flMnPlan_ForSelect)
  , SpSopr.Npp
  (fieldName = flSpSopr_Npp)

  , mtMnPlan_Selected_Loop.Num
  (fieldName = flMnPlan_Sel_Num)

  , KAtMc_mtForReport.Barkod
  (FieldName = flForRep_Barkod )
  ,MnPlan_mtForReport.Number
  (FieldName = flForRep_mtForReport)

  ,mtMC_List_Skl_Kol.dKOl
  (FieldName = flSklOst)

  ,mtForReport.dKol_Req - mtForReport.dKol_Res
  (FieldName = flNotReserved)

from
  KatMc
  , KatMc KatMc_Get
  , MnPlan
  , MnPlan OsnZak
  , MnPlan Vp
  , MnPlan MnPlan_All
  , KatNotes
  , SpMnPlan
  , SpMnPlan SpMnPlan_Osn
  , SpMnPl
  , ValSpMnP
  , Indent
  , Claim
  , Claim Claim_2
  , SaldoObj
  , SaldoRaz
  , SaldoObj SaldoObj_Total
  , KatSopr
  , SpSopr
  , KatMc MC_SpSopr

  , mtClaim_Mc
  , mtValSpMnP_Kol
  , ResultTable
  , mtForReport
  , mtForReport mtForReport_Loop
  , mtMnPlan_Selected
  , mtMnPlan_Selected mtMnPlan_Selected_2
  , mtMnPlan_Selected mtMnPlan_Selected_3
  , mtMnPlan_Selected mtMnPlan_Selected_Loop
  , mtMC_List
  , mtMC_List mtMC_List_Rep
  , mtMC_List mtMC_List_Skl_Kol
  , KAtMc KatMc_mtForReport
  , MnPlan MnPlan_mtForReport
  , mtSaldoRaz
  , mtSpMnplan
where
((
  0 == KatMc.isArch

  and vw_cMc == KatMc_Get.Nrec

  and vw_MnPlanNrec == MnPlan.Nrec

  and MnPlan.cStatus /== KatNotes.nRec

  //Приходные накладные
  and 101 == KatSopr.VidSopr

  and OSN_ZAK_WAY == MnPlan_All.CWAYACCOU (noindex)
  and 17          == MnPlan_All.TypePlan // (noindex)
  and 0          <<= MnPlan_All.Act

  and OSN_ZAK_WAY == OsnZak.CWAYACCOU (noindex)
  and 17          == OsnZak.TypePlan // (noindex)
  and 0          <<= OsnZak.Act

  and mtMnPlan_Selected_2.cMnPlan     == SpMnPlan_Osn.cMnPlan
  and 0                            <<= SpMnPlan_Osn.NumSort
  and 1000000000150h == SpMnPlan_Osn.cVal1 (noindex)

  and mtMnPlan_Selected.cMnPlan  /== mtSpMnplan.cMnplan
  and vw_cMc                     /== mtSpMnplan.cIzd

  and VP_WAY  == VP.CWAYACCOU (noindex)
  and 17      == VP.TypePlan  //(noindex)
  and 0      <<= VP.Act

  and vw_cSpMnPlan == SpMnPl.cSpMnPlan
  and SpMnPl.Nrec == ValSpMnP.cSpMnPl

  //and vw_MnPlanNrec  == ObjAcct.cObject
  and 0 <<= ObjAcct.cObject
  and 17 == ObjAcct.TypeObj

  and ObjAcct.cOwner == SpSopr.cSopr   //(noindex)
  and 0 <<= SpSopr.NPP
  and '501' == SpSopr.VidSopr (noindex)

  //Количество согласовано
  and vw_MnPlanNrec     == Indent.cValKau[1](noindex)
  and 1000000000006h    == Indent.cType (noindex)
  and MnPlan.STARTDATE <<= Indent.dInd

  and Indent.nRec == Claim.cIndent (noindex)
  and vw_cMc      == Claim.cMcUsl (noindex)

  //количество зарезервировано на заказ
  and mtMnPlan_Selected_3.cMnPlan /== mtSaldoRaz.cMnPlan
  and mtSaldoRaz.nRec             /== saldoObj.cSaldoRaz
  and 0                           <<= SaldoObj.dOper

  //резерв по всем заказам
  and vw_cMc               == SaldoRaz.cMc    (noindex)
  and 0                    == SaldoRaz.wMode  (noindex)

  and SaldoRaz.Nrec == SaldoObj_Total.cSaldoRaz //(noindex)
  and 0             <<= SaldoObj_Total.dOper
  //остатки на всех складах
  and vw_cMc  == SklOst.cMc
  and 0       == SklOst.Sp

  and vw_Filial_name == Filials.name (noindex)

  and vw_cMc /== Claim_2.cMcUsl// (noindex)
  and vw_PrMc == Claim_2.PrMc

  and mtForReport.cMc     == KAtMc_mtForReport.NRec
  and mtForReport.cMnPlan == MnPlan_mtForReport.NRec
  and mtForReport.cMc     == mtMC_List_Skl_Kol.cMc
))

order by
  SaldoObj.dOper
  , SaldoObj_Total.dOper
  , ResultTable.cMnPlan
  , ResultTable.wType
  , mtMnPlan_Selected.Num
bounds
  BySklad =     vw_cMc     == SklOst.cMc
            and 0          == SklOst.Sp
            and vw_cSklad /== SklOst.cPodr
;

var
  p_MarkerMC: IMarker(marker) new;
  MarkerMC: LongInt;

//#region Визуализация
  screen scSelectMC;
    show at (,, 75, 9);
    fields
      flTypeSelMC: noprotect;
      flMC_List: pickbutton;
      flMC_Indent: pickbutton;
  <<
    Выбор МЦ для составления отчета
    (.) `из списка МЦ             .@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    (.) `из приходной накладной   .@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  >>
  end;

screen scSelTypeReport 'Тип формируемого отчета';
  show at(76,,, 9);
  fields
    flTypeRep: noprotect;
  <<
    Тип формируемого отчета
    (.) `Excel
    (.) `На экран
  >>

end;

screen scMnPlan;
  show at (, 10,, 12);
  fields
    wSelecSub: noprotect;
<<
  [.] `Выбрать заказы для составления отчета
  [.] `выбирать с подзаказами
>>
end;

browse brMnPlanForSelect 'Заказы';
  show at (,13,30,21);
  table MnPlan_All;
  fields
    flMnPlan_ForSelect ' Заказ ' : [20], protect;
end;

browse brMnPlan_Selected 'Выбранные заказы';
  show at (31,13,,21);
  table mtMnPlan_Selected_Loop;
  fields
    flMnPlan_Sel_Num              ' № '    : [5] , noprotect;
    mtMnPlan_Selected_Loop.Number ' Заказ' : [20], protect;
end;

screen scMnPlanSelected;
  show at (31, 13,, 21);
<<

  ДЛЯ СОСТАВЛЕНИЯ ОТЧЕТА ИСПОЛЬЗУЮТСЯ
  ОСНОВНЫЕ ЗАКАЗЫ И ВЕДОМОСТИ ПОКУПНЫХ

>>
end;

screen scCommand;
  show at (, 22,, 23);
  buttons
    cmEnter;
<<
  <. Начать формирование отчета .>
>>

end;
//#endregion

//#region Всё для Excel
function WriteExcelLine(sVal: string; _iRow: integer; _iCol: integer): void;
{
  xlSetCellStringValue(sVal, _iRow, _iCol, _iRow, _iCol);
}

Function CreateExcel_Header: void;
{
  WriteExcelLine('Наименование', START_ROW, MC_COL);
  WriteExcelLine('Обозначение', START_ROW, MC_COL + 1);
  WriteExcelLine('Баркод', START_ROW, MC_COL + 2);
  WriteExcelLine('Заказ', START_ROW, ORDER_COL);
  WriteExcelLine('Потребность', START_ROW, REQUARED_COL);
  WriteExcelLine('Отпущено', START_ROW, RELEASED_COL);
  WriteExcelLine('Согласовано', START_ROW, AGREED_COL);
  WriteExcelLine('Резерв', START_ROW, RESERVED_COL);
  WriteExcelLine('Свободный остаток', START_ROW, FREE_OST_KOL);
  WriteExcelLine('Резерв по другим заказам', START_ROW, RESERVED_OTHER_KOL);
  WriteExcelLine('Статус заказа', START_ROW, MNPLAN_STATUS_KOL);
}

Function CreateRep_ResTbl(_CurRow: integer): integer;
{
  result := _CurRow;
  _Loop mtForReport
  {
      //выводим МЦ
    ++result;
    if (GetFirst FastFirstRow katMc where ((mtForReport.cMc == KatMc.Nrec)) = tsOk)
    {
      WriteExcelLine(KatMc.Name, result, MC_COL);
      WriteExcelLine(KatMc.Obozn, result, MC_COL + 1);
      WriteExcelLine(KatMc.Barkod + '_', result, MC_COL + 2);
    }

    vw_MnPlanNrec := mtForReport.cMnPlan

    if (GetFirst FastFirstRow MnPlan = tsOK)
    {
      WriteExcelLine(MnPlan.Number, result, ORDER_COL);
      if(GetFirst FastFirstRow KatNotes = tsOk)
        WriteExcelLine(KatNotes.Name, result, MNPLAN_STATUS_KOL);
    }

      //Выводим количества
    WriteExcelLine(mtForReport.dKol_Req, result, REQUARED_COL);
    WriteExcelLine(mtForReport.dKol_Rel, result, RELEASED_COL);
    WriteExcelLine(mtForReport.dKol_Agr, result, AGREED_COL);
    WriteExcelLine(mtForReport.dKol_Res, result, RESERVED_COL);

      //Общее для всех позиций
    WriteExcelLine(TotalOst - TotalReserv, result, FREE_OST_KOL);
    WriteExcelLine(TotalReserv, result, RESERVED_OTHER_KOL);
  }
}

Function SetExcelFormat: void;
var
  i: integer;
{
  xlFreeze(START_ROW + 1, ORDER_COL);
  xlAutoFit(START_ROW, MC_COL, iCurRow, MNPLAN_STATUS_KOL);
  //выделяем рамкой каждую ячейку
  for(i := MC_COL; i <= MNPLAN_STATUS_KOL; ++i)
    xlFrameCells(31, 2, 1, 1, START_ROW + 1, i, iCurRow, i);
}

Function InitExcel: void;
{
  sFile := 'c:\galtemp\Release_Reserv.xls';

  DeleteFile(sFile);

  if (not xlOpenNewExcel(true))
    Message('Не удалось открыть Excel')
}

Function WriteMC(_iRow: integer): void;
{
  if(GetFirst FastFirstRow KatMc_Get = tsOk)
  {
    WriteExcelLine(KatMc_Get.Name, _iRow, MC_COL);
    WriteExcelLine(KatMc_Get.Obozn, _iRow, MC_COL + 1);
    WriteExcelLine(KatMc_Get.BarKod + '_', _iRow, MC_COL + 2);
  }
}

Function WriteMnPlan: boolean;
{
  ++iCurRow;
  if(GetFirst FastFirstRow MnPlan = tsOk)
    WriteExcelLine(MnPlan.Number, iCurRow, ORDER_COL);

  WriteMC(iCurRow);

  WriteExcelLine(TotalOst - TotalReserv, iCurRow, FREE_OST_KOL);

  if(GetFirst FastFirstRow KatNotes = tsOK)
    WriteExcelLine(KatNotes.Name, iCurRow, MNPLAN_STATUS_KOL);

  result := false;
  //Message('Найден заказ');
}
//#endregion

Window wnSelectMC 'Выбор списка МЦ для составления отчета';

  browse brKatMcWn;
   show at (,,,);
  table KatMc;
    recMarker = p_MarkerMC{flMCNrec};
  fields
    flMcBarkod   'Баркод'       : [10], protect;
    flMcObozn    'Обозначение'  : [20], protect;
    flMcName     'Наименование' : [20], protect;
  end;

WindowEvent wnSelectMC;
  cmDone:
  {
    set flMC_List := 'Выбран набор МЦ';
  }

end;
end;

Window wnSlcNakl 'Выбор приходной' dialog;

  browse brPriNakl 'приходные накладные';
    show at (,,,15);
    table KatSopr;
    fields
      KatSopr.NSopr 'номер накладной'    : [20], protect;
      KatSopr.Descr 'Дескриптор'         : [20], protect;
      KatSopr.dSopr 'Выписана'           : [20], protect;
      KatSopr.dOpr  'Дата оприходования' : [20], protect;
  end;

  browse brmtMC_List 'Спецификация приходной накладной'
    show at (,16,,);
    table mtMC_List;
    fields
      mtMC_List.Npp       'Номер позиции' : [ 5], protect;
      mtMC_List.MC_BarKod 'Баркод'        : [20], protect;
      mtMC_List.dKol      'Количество'    : [10], protect;
  end;

  Procedure Fill_mtMC_List(_cKatSopr: comp);
  var
    iNum: integer;
  {
    mtClear(#mtMC_List, mfNormal);
    iNum := 0;

    vw_cKatSopr := KatSopr.NRec;

    _Loop SpSopr where ((KAtSopr.NRec == SpSopr.cSopr))
    {
      ++iNum;
      vw_cMc := SpSopr.cMCUSL;
      if (GetFirst FastFirstrow KatMc_Get = tsOK) //       == KatMc_Get.Nrec
        insert into mtMC_List set
                    mtMC_List.cKatSopr := KatSopr.NRec
                  , mtMC_List.Npp := SpSopr.Npp
                  , mtMC_List.MC_BarKod := KAtMc_Get.BarKod
                  , mtMC_List.dKol := SpSopr.Kol
                  , mtMC_List.cmc  := SpSopr.cMCUSL;
    }

    ReReadRecord(#mtMC_List);
  }

  windowEvent  wnSlcNakl;
    cmDefault:
    {
      Fill_mtMC_List(KatSopr.NRec);
    }

    cmDone:
    {
      set flMC_Indent := 'Выбрана накладная ' + KatSopr.NSopr;
      vw_cSklad := KatSopr.cPodrTo;
    }
  end;

end;

Window wnRasprReserv 'Распределение резерва';

  browse brRasprReserv;
    show at (,,,);
    table mtForReport;
    fields
      flForRep_Barkod           'МЦ'               : [20], protect;
      flForRep_mtForReport      'Заказ'            : [20], protect;
      mtForReport.dKol_Req      'Требуется'        : [20], protect;
      mtForReport.dKol_Rel      'Отпущено'         : [20], protect;
      mtForReport.dKol_Agr      'Согласовано'      : [20], protect;
      mtForReport.dKol_Res      'Зарезервировано'  : [20], protect;
      mtForReport.dKol_NotRsvd  'Нет резерва'      : [20], protect;
      flSklOst                  'Ост на складе'    : [20], protect;
      mtForReport.dKol_DoReserv 'Создать резерв'   : [20], protect;
  end;

end;

//*********************************************
Function GetTotalReserved: double;
{
  result := 0;

  _Loop SaldoRaz
    _Loop SaldoObj_Total
    {
      result += SaldoObj_Total.Kol;
    }
}

Function GetTotalSklOst: double;
{
  result := 0;
  _Loop SklOst
    result += SklOst.Kol;
}
//*********************************************

//+++++++++++++++++++++++++++++++++++++++++++++++++++++
Function AddFillial(_Fil_name: string): void;
{
  vw_Filial_name := _Fil_name;

  If (GetFirst FastFirstRow Filials = tsOk)
  {
    if(UserHelper:: userInFilial(UserId(), Filials.atl_Nrec))
    {
      SortedContainer_Insert(Filials, Filials.atl_Nrec);
    }
    else
    {
      Message('Вам запрещено работать в филиале ' + _Fil_name + Chr(13) +
      'отчет будет сформирован без учета информации по этому филиалу ');
    }
  }
  else
    Message('не удалось найти филиал ' + _Fil_name);
}

Function SelectFilials: void;
{
  Filials := SortedContainer_Init('', 8, 10, 2, false);
  SortedContainer_DeleteAll(Filials);

  AddFillial('НЗЛ');
  AddFillial('РЭПХ');
  AddFillial('К-Энерго');
  AddFillial('ЭП');

  SetBranches(Filials, 0);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++

//-------------------------------------------------------
//создаём таблицы в памяти для ускорения работы алгоритма
Function Fill_mtClaim_Mc(_cMc: comp): void;
var
  wPrMc: array [1..4] of word;
  i: word;
{
  mtClear(#mtClaim_Mc, mfNormal);

  wPrMc[1] := 0;
  wPrMc[2] := 1;
  wPrMc[3] := 2;
  wPrMc[4] := 4;

  for(i := 1; i < 5; ++i)
  {
    vw_PrMc := wPrMc[i];
    _Loop Claim_2
      if(GetFirst FastFirstRow Indent where ((Claim_2.cIndent == Indent.nRec
            and (Indent.cState = 281474976710740
            or Indent.cState = 281474976710943
            or Indent.cState = 281474976711054))) = tsOk)
      {
        insert into ResultTable set
          ResultTable.cMc := _cMc
        , ResultTable.cMnPlan := Indent.cValKau[1]
        , ResultTable.dKol := Claim_2.Kol
        , ResultTable.wType := AGREED;
      }
  }
}

Function GetValSpMnP_Kol(_cSpMnPlan: comp): double;
{
  vw_cSpMnPlan := _cSpMnPlan
  if (GetFirst FastFirstRow SpMnPl = tsOK)
    if (GetFirst FastFirstRow ValSpMnP = tsOk)
      result := ValSpMnP.Kol;
}

Function Fill_mtValSpMnP_Kol(_cMc: comp): void;
{
  mtClear(#mtValSpMnP_Kol, mfNormal);

  _Loop mtMnPlan_Selected
    _Loop mtSpMnplan
    {
      insert into ResultTable set
                  ResultTable.cMc     := _cMc
                , ResultTable.cMnPlan := mtSpMnplan.cMnPlan
                , ResultTable.dKol    := GetValSpMnP_Kol(mtSpMnplan.nRec)
                , ResultTable.wType   := REQUARED;
    }
}

Function AddReleased(_cMc: comp): void;
{
  insert into ResultTable
  (
  cMc
  , cMnPlan
  , dKol
  , wType
  )
  select
  SpSopr.cMcusl
  , ObjAcct.cObject
  , SpSopr.KolFact
  , RELEASED
  from
  SpSopr
  , ObjAcct
  where
  ((
  _cMc == SpSopr.cMcUsl
  and 501 == SpSopr.VidSopr
  and 0 <<= SpSopr.dOprTTN
  and SpSopr.cSopr == ObjAcct.cOwner
  and 17 == ObjAcct.TypeObj
  ));
}

Function AddReserved(_cMc: comp): void;
{
  _Loop mtMnPlan_Selected_3
    _Loop mtSaldoRaz
      _loop SaldoObj
      {
        insert into ResultTable set
                    ResultTable.wType   := RESERVED
                   ,ResultTable.cMc     := _cMc
                   ,ResultTable.cMnPlan := mtSaldoRaz.cMnPlan
                   ,ResultTable.dKol    := SaldoObj.Kol;
      }
}

Function mtForReport_Report: void;
{
  DeleteFile(FOR_REPORT_LOG);

  LogStrToFile(FOR_REPORT_LOG, Cur_Date + ' LogDate');

  _Loop mtForReport_Loop
  {
    vw_MnPlanNrec := mtForReport_Loop.cMnPlan;
    if (GetFirst FastFirstRow MnPlan = tsOk)
      LogStrToFile(FOR_REPORT_LOG,
      mtForReport.cMc +
      ' ' + MnPlan.number +
      ' Req ' + mtForReport.dKol_Req +
      ' Rel ' + mtForReport.dKol_Rel +
      ' Agr ' + mtForReport.dKol_Agr +
      ' Res ' + mtForReport.dKol_Res);
  }

  LogStrToFile(FOR_REPORT_LOG, '');
  LogStrToFile(FOR_REPORT_LOG, 'mtMC_List_Selected');

  _Loop mtMC_List_Rep
    LogStrToFile(FOR_REPORT_LOG, mtMC_List_Rep.cMc + ' ' + mtMC_List_Rep.MC_BarKod + ' Qlt ' + mtMC_List_Rep.dSkl);

  LogStrToFile(FOR_REPORT_LOG, '');
  LogStrToFile(FOR_REPORT_LOG, 'mtMnPlan_Selected');

  _Loop mtMnPlan_Selected_Loop
  {
    LogStrToFile(FOR_REPORT_LOG, mtMnPlan_Selected_Loop.Number);
  }
}

Function IsSelMnPlan(cMnPlan: comp; wType: word): boolean;
{
  result := false;
  if (GetFirst FastFirstRow mtMnPlan_Selected
      where ((cMnPlan == mtMnPlan_Selected.cMnPlan)) = tsOK)
  {
    result := true;
  }
  else
  {
    vw_MnPlanNrec := cMnPlan;
    if (GetFirst FastFirstRow MnPlan = tsOk)
    {
      LogStrToFile('D:\NotFound.txt', MnPlan.Number);
      if (MnPlan.cWayAccou = VP_WAY)
        result := true;
    }
  }
}

procedure RaspredPrihkol;
var
  dCurPrih_Qlt: double; //нераспределённое кол-во из прих. накладной
{
   #ifDef IsTestMode
    LogStrToFile(RASPRED_LOG, 'Start, wSelecSub = ' );
   #end

  //if ( wSelecSub > 0 )
  {
      _Loop mtMC_List_Rep
      {
        dCurPrih_Qlt := mtMC_List_Rep.dKol;
        #ifDef IsTestMode
          LogStrToFile(RASPRED_LOG, mtMC_List_Rep.MC_BarKod);
        #end
        _Loop mtMnPlan_Selected_Loop
        {
          #ifDef IsTestMode
            LogStrToFile(RASPRED_LOG, mtMnPlan_Selected_Loop.Number);
          #end
          if(dCurPrih_Qlt > 0)
          {
            if (GetFirst FastFirstRow mtForReport where
            ((   mtMC_List_Rep.cMc == mtForReport.cMc
and mtMnPlan_Selected_Loop.cMnPlan == mtForReport.cMnPlan)) = tsOK )
             {
                  if (mtForReport.dKol_NotRsvd > 0)
                  {
                    if(mtForReport.dKol_NotRsvd > dCurPrih_Qlt )
                    {
                      mtForReport.dKol_DoReserv := dCurPrih_Qlt;
                      dCurPrih_Qlt := 0;
                    }
                    else
                    {
                       mtForReport.dKol_DoReserv := mtForReport.dKol_NotRsvd;
                       dCurPrih_Qlt -= mtForReport.dKol_NotRsvd;
                    }

                    update current mtForReport;
                  }
                #ifDef IsTestMode
                  LogStrToFile(RASPRED_LOG, mtMC_List_Rep.MC_BarKod + ' ' + mtMnPlan_Selected_Loop.Number + dCurPrih_Qlt );
                #end
             }
          }
          else
          {
            break;
          }
        }
      }
  }
}

function Upd_mtForReport_Kol(_cMc: comp; cMnplan: comp; _wType: word; _dKol: double): void;
{
  if (GetFirst FastFirstRow mtForReport where ((_cMc == mtForReport.cMc
        and cMnplan == mtForReport.cMnplan)) = tsOK)
    case _wType of
      REQUARED: update current mtForReport set mtForReport.dKol_Req = mtForReport.dKol_Req + _dKol;

      RELEASED: update current mtForReport set mtForReport.dKol_Rel = mtForReport.dKol_Rel + _dKol;

      AGREED:   update current mtForReport set mtForReport.dKol_Agr = mtForReport.dKol_Agr + _dKol;

      RESERVED: update current mtForReport set mtForReport.dKol_Res = mtForReport.dKol_Res + _dKol;
    end;
}

Function PrepareResultTable: void;
var
  cCurMc: comp;
  cCurMnPlan: comp
  wCurType: word;
{
  _Loop ResultTable
  {
    //Message(' Перед проверкой на заказ');
    if(IsSelMnPlan(ResultTable.cMnPlan, ResultTable.wType))
    {
     // Message(' Создаём запись в mtForReport ');
      if (GetFirst FastFirstRow mtForReport where
           ((ResultTable.cMc == mtForReport.cMc
     and ResultTable.cMnPlan == mtForReport.cMnplan)) != tsOk)
      {

        insert into mtForReport set
                    mtForReport.cMc      := ResultTable.cMc
                  , mtForReport.cMnplan  := ResultTable.cMnPlan
                  , mtForReport.dKol_Req := 0
                  , mtForReport.dKol_Rel := 0
                  , mtForReport.dKol_Agr := 0
                  , mtForReport.dKol_Res := 0;
      }

      Upd_mtForReport_Kol(ResultTable.cMc, ResultTable.cMnPlan, ResultTable.wType, ResultTable.dKol);
    }
  }

  _Loop mtForReport_Loop
  {
    mtForReport_Loop.dKol_NotRsvd := mtForReport_Loop.dKol_Req - mtForReport_Loop.dKol_Res;
    update current mtForReport_Loop;
  }

  RaspredPrihkol();

#ifdef IsTestMode
  mtForReport_Report();
#end
}

Function ReportResultTable: void;
{
  LogStrToFile(RESULT_TABLE_LOG, 'Start');

  _Loop ResultTable
    {
    if (GetFirst FastFirstRow MnPlan where ((ResultTable.cMnPlan == MnPlan.Nrec)) = tsOk)
      LogStrToFile(RESULT_TABLE_LOG, ResultTable.cMc + ' ' + MnPlan.number + ' qlt ' + ResultTable.dKol + ' тип ' + ResultTable.wtype);
  }
}

procedure Fill_mtSaldoRaz(_cMc: comp);
{
  mtClear(#mtSaldoRaz, mfNormal);

  _loop Saldoraz
  {
    insert into mtSaldoRaz
           set  mtSaldoRaz.cmc     := saldoraz.cMC
               ,mtSaldoRaz.cMnPlan := SaldoRaz.cObj
               ,mtSaldoRaz.nRec    := saldoraz.NRec
  }
}

function Fill_ResultTable(_cMc: comp): void;
{
  AddReleased(vw_cMc);
  #ifdef IsTestMode
    LogStrToFile(PROFILER_LOG, Cur_Time + ':' + Second(Cur_Time) + ' Released');
  #end

  Fill_mtClaim_Mc(vw_cMc);
  #ifdef IsTestMode
    LogStrToFile(PROFILER_LOG, Cur_Time + ':' + Second(Cur_Time) + ' Claim');
  #end

  Fill_mtValSpMnP_Kol(vw_cMc);
  #ifdef IsTestMode
    LogStrToFile(PROFILER_LOG, Cur_Time + ':' + Second(Cur_Time) + ' Valkol');
  #end

  Fill_mtSaldoRaz(vw_cMc);
  AddReserved(vw_cMc);
  #ifdef IsTestMode
    LogStrToFile(PROFILER_LOG, Cur_Time + ':' + Second(Cur_Time) + ' Reserved');
  #end

  #ifdef IsTestMode
    ReportResultTable();
    LogStrToFile(PROFILER_LOG, Cur_Time + ':' + Second(Cur_Time) + ' End');
  #end
}

procedure Fill_mtSpMnplan;
{
  mtClear(#mtSpMnplan, mfNormal);

  _Loop mtMnPlan_Selected_2
    _loop SpMnPlan_Osn
    {
      insert into mtSpMnplan
              set mtSpMnplan.nRec    := SpMnPlan_Osn.nrec
                 ,mtSpMnplan.cMnplan := SpMnPlan_Osn.cMnPlan
                 ,mtSpMnplan.cIzd    := SpMnPlan_Osn.cIzd;
    }
}

//-----------------------------------------------------------
//Список заказов для составления отчета
function Insert_MnPlan(cMnPlan: comp): void;
{
  vw_MnPlanNrec := cMnPlan;
  if(GetFirst FastFirstRow mtMnPlan_Selected
      where ((vw_MnPlanNrec == mtMnPlan_Selected.cMnPlan)) != tsOK)
  {
    if (GetFirst FastFirstRow MnPlan = tsOk)
    {
      insert into mtMnPlan_Selected
              set mtMnPlan_Selected.cMnPlan = MnPlan.nrec
                , mtMnPlan_Selected.Num     = ++iMnPlan
                , mtMnPlan_Selected.Number  = MnPlan.Number
                , mtMnPlan_Selected.Name    = MnPlan.Name
    }
  }
  else
    Message('Этот заказ уже выбран для составления отчета');
}

function Ins_mtMnPlan_Selected(cMnPlan: comp): void;
{
  if(wSelecSub > 0)
  {
    if (wSelecSub = 1)
    {
      Insert_MnPlan(cMnPlan);
    }
    else
      _Loop SpMnPlan where ((cMnPlan /== SpMnPlan.cMnPlan
        and 0 <<= SpMnPlan.Number
        and 17 /== SpMNPlan.TypeIzd (noindex)))
      {
        Insert_MnPlan(SpMnPlan.cIzd);
      }
  }

  ReReadRecord(#mtMnPlan_Selected_Loop);
}

procedure RestoreNum;
var
  curNum: integer;
{
  curNum := 0;
  _Loop mtMnPlan_Selected
  {
    ++curNum;
    mtMnPlan_Selected.Num := curNum;
    update current mtMnPlan_Selected
  }

  iMnPlan := curNum;
}

Function CreateReportLine: void;
var
  iStartRow: integer;
{
  iStartRow := iCurRow;

  LogStrToFile(PROFILER_LOG, '');
  if( GetFirst FastFirstRow KatMc_Get = tsOK )
    LogStrToFile(PROFILER_LOG, Cur_Time + ' ' + KatMc_Get.BarKod );

  Fill_ResultTable(vw_cMc);

  --iCurRow; // для правильного вывода списка основных заказов

  //Количество резерва по всем заказам
  TotalReserv := GetTotalReserved;

  mtMC_List.dSkl := GetTotalSklOst;
  update current mtMC_List;

  TotalOst := GetTotalSklOst;

  PrepareResultTable();

  //Составляем отчет
  case flTypeRep of
    0:
    {
      ++iCurRow;
      WriteMC(iCurRow);
      xlSetFontStyle(1, iCurRow, MC_COL, iCurRow, MC_COL + 2);
      iCurRow := CreateRep_ResTbl(iCurRow);
    }
  end;

  if(iStartRow = iCurRow)
      ++
    iCurRow;
}

Procedure PrepareAllLogs;
{
  DeleteFile(RESULT_TABLE_LOG);
  DeleteFile(FOR_REPORT_LOG);
  DeleteFile(PROFILER_LOG);
  DeleteFile(RASPRED_LOG);
}

Function InitProcess: void;
var
  i: integer;
{
  StartNewVisual(vtRotateVisual, vfTimer, 'Подготовка к формированию отчета', 1);

  #ifdef IsTestMode
    PrepareAllLogs();
  #end

  SelectFilials;

  if (flTypeRep = 0)
  {
    InitExcel;
    CreateExcel_Header;
    iCurRow := START_ROW;
  }

  if(wSelecSub = 0)
  {
    mtClear(#mtMnPlan_Selected, mfNormal);
    _Loop MnPlan_All
    {
      Insert_MnPlan(MnPlan_All.NRec);
    }
  }

  Fill_mtSpMnplan();

  case flTypeSelMC of
  0 :  {
    mtClear(#mtMC_List, mfNormal);

    MarkerMC := InitMarker('', 8, 10, 10, false);
    p_MarkerMC.ExportTo(MarkerMC);

    for(i := 0; i < GetMarkerCount(MarkerMC); ++i)
    {
      GetMarker(MarkerMC, i, vw_cMc);

      if (GetFirst FastFirstRow KatMc_Get = tsOk)
        insert into mtMC_List
                set mtMC_List.cMc       := vw_cMc
                    mtMC_List.MC_Name   := KatMc_Get.Name
                    mtMC_List.MC_BarKod := KatMc_Get.BarKod;
    }
  }

  1 : PushBounds(tbBySklad);

  end;

  mtClear(#ResultTable, mfNormal);
  mtClear(#mtForReport, mfNormal);

  StopVisual('Подготовка отчета завершена', vfHigh1);
}

Function EndProcess: void;
{
  ClearMarker(MarkerMC);
  DoneMarker(MarkerMC, '');

  xlSaveWorkBookByName(sFile);
  SetExcelFormat;
  xlKillExcel;

  BranchHelper:: reSetBranches;
}

Function Process(): void;
{
  InitProcess;

  StartNewVisual(vtNumericVisual, vfTimer, 'Формирование отчета', 1);

  _Loop mtMC_List
  {
    vw_cMc := mtMC_List.cMc;

    CreateReportLine;

    NextVisual;
  }

  StopVisual('Формирование отчета завершено', vfHigh1);

  RunWindow(wnRasprReserv);

  EndProcess;
}

Procedure SetMnPlanSel_Format;
{
  if(wSelecSub < 1)
    SetFormat(scMnPlanSelected)
  else
    SetFormat(brMnPlan_Selected);
}

handleEvent
  cmInit:
  {
    iMnPlan := 0;
    SetFormat(scMnPlanSelected);
  }

  cmEnter:
  {
    Process();
  }

  cmCheckField:
  {
    case CurField of
      #wSelecSub:
      {
        SetMnPlanSel_Format();
      }

      #flMnPlan_Sel_Num:
      {
        mtMnPlan_Selected_Loop.Num := mtMnPlan_Selected_Loop.Num;
        update current mtMnPlan_Selected_Loop;
        ReReadRecord(#mtMnPlan_Selected_Loop);
      }

    end;
  }

  cmPick:
  {
    case CurField of
      #flMC_List:
      {
        RunWindow(wnSelectMC);
      }

      #flMC_Indent:
      {
        RunWindow(wnSlcNakl);
      }

    end;
  }

end;

tableEvent table MnPlan_All
  cmDefault:
  {
    Ins_mtMnPlan_Selected(MnPlan_All.nRec);
  }

end;

tableEvent table mtMnPlan_Selected
  cmDelete:
  {
    Delete current mtMnPlan_Selected;
    RestoreNum;
  }
end;

end.

#include UserReport.vih
VipInterface UserReport_Release_Reserv_Zakaz_Report Implements IUserReport Licensed(Free);

Interface UserReport_Release_Reserv_Zakaz_Report;

create view;

function VisibleInModule(Ind: Byte): String;
begin
  VisibleInModule := '';
  case Ind of
    1: VisibleInModule := 'MANUFPLAN'; // модули, где должен отображаться  (* - все модули)

    2: VisibleInModule := 'BUY';

    3: VisibleInModule := 'SKLAD';

  end;
end;

function GetPriority: Integer;
begin
  GetPriority := 0;
end;

function GetGroupName (Level: Word): String;
begin
  GetGroupName := '';
  case Level of
    1: GetGroupName := 'Резервирование';
   // название группы отчетов/ интерфейсов
  end;
end;

function GetReportName: String;
begin
  GetReportName := 'Отчет по отпуску и резерву на заказ' // название (которое будет отображаться в списке)
end;
!-------------------------------------------------------------------------------
procedure Run;
begin
  runinterface(Release_Reserv_Zakaz_Report);
end;
!-------------------------------------------------------------------------------
end.
Программист-самоучка
aks
Сообщения: 7
Зарегистрирован: 17 июл 2013, 13:54

Re: Первые шаги по OLAP

Сообщение aks »

развитие OLAP-отчетов идет на версии 5.5. последние изменения в 5.4 были от апреля прошлого года. за это время было ооочень многое исправлено и доработано.
попробую проверить пример на обеих версиях.
Zver
Местный житель
Сообщения: 204
Зарегистрирован: 13 ноя 2012, 12:47
Откуда: СПб
Контактная информация:

Re: Первые шаги по OLAP

Сообщение Zver »

Понятно.

Тогда откладываем освоение OLAP до перехода на 9.1 (ориентировочно - январь 2014 ).
Программист-самоучка
Ответить