Category: it

Category was added automatically. Read all entries about "it".

Создаём собственные отчёты в Excel

Мы будем подключаться к Экселю как к COM-серверу. Следовательно он должен быть установлен на компьютере. Мы можем запускать эксель (читать файлы, писать файлы, показывать на экран) как на сервере (если это винда), так и на компьютере клиента. В первом случае нам надо использовать серверный скрипт, во втором браузерный.

Пример серверного скрипта для работы с экселем (только если сибель установлен под виндой)

var ExcelIns = COMCreateObject("Excel.Application");
ExcelIns.Visible = true;
ExcelIns.WorkBooks.Add();
var masRows:Array=this.BusComp().GetFieldValue("Identificator").split("\n");
var masColls:Array;
for(var i=0;i<masRows.length;i++){
masColls=masRows[i].split(";");
for(var j=0;j<masColls.length;j++)
ExcelIns.ActiveSheet.Cells(i+1,j+1).Value = masColls[j];
masColls=null;
}

masRows=null;
//ExcelIns.Application.Quit();
ExcelIns=null;

Пример браузерного скрипта для работы с экселем.

При использовании браузерного скрпита аплета следует помнить, что в нём доступны только те поля БК, которые вынесены на сам аплет (плюс пять обязательных полей).

Также следует помнить, что из браузерного скрипта аплета можно вызывать сначала браузерный, а потом одноимённый серверный скрипты БС (а из серверного скрипта аплета только серверный скрипт БС)

Итак, у нас на бк есть длинное поле типа DTYPE_NOTE и размером 16 383 (в базе оно имеет тип long). Мы заполняем это поле в серверном скрипте (или где-то ещё). В этом поле хранится отчёт, который должен быть показан в экселе.

в бразуерном скрипте аплета по нажатию кнопки мы показываем отчёт путём вызова метода из БС и передачи ему значения из нашего длинного поля

var svc = TheApplication().GetService("CommonUtilsBS");
var inputPropSet = TheApplication().NewPropertySet();
inputPropSet.SetProperty("ReportString", this.BusComp().GetFieldValue("Identificator"));
svc.InvokeMethod("ShowReport", inputPropSet);
inputPropSet=null; svc=null

вот код этого БС


if (methodName=="ShowReport"){
//TheApplication().SWEAlert("la-la-la1");
var txt=inputPropSet.GetProperty("ReportString");
var ExcelIns = new ActiveXObject("Excel.Application");
ExcelIns.Visible = true;
ExcelIns.WorkBooks.Add();
var masRows=txt.split("\n");
//var masColls;
var i;
for(i=0;i<masRows.length;i++){
masColls=masRows[i].split(";");
for(var j=0;j<masColls.length;j++)
ExcelIns.ActiveSheet.Cells(i+1,j+1).Value = masColls[j];
masColls=null;
}
masRows=null;
//ExcelIns.Application.Quit();
ExcelIns=null;
txt=null;
return ("CancelOperation");
}

Передача данных из серверного скрипта аплета в браузерный скрипт другого аплета. Всплывающие (popup)

Всплывающие (popup) аплеты

http://siebelunleashed.com/how-popup-applet-through-escript/
http://siebelunleashed.com/how-to-invoke-popup-applet-on-button-click/
http://siebelmantra.blogspot.ru/2013/08/how-to-display-popup-applet-in-siebel.html

Примечание: всплывающий аплет обязательно должен быть настроен на БК принадлежащий тому же БО, что и представление с которого он запускается. То есть всё как обычно. Работа ведётся в пределах одного БО. Всплывающий аплет должен быть основан на определённом классе. Например на CSSFramePopup

Передавать данные из серверного скрипата в браузерный скрипт другого аплета на самом деле оказывается просто. И делается это следующим образом

Пусть в серверном скрипте одного аплета у нас есть строковая переменная var TextData:chars=""; (а запихнуть в неё можно охренительно большие массивы символов).

В серверном скрипте первого аплета мы записываем нашу текстовую переменную в создаваемый пользовательский атрибут

TheApplication().SetProfileAttr("TextData", TextData);

Потом вызываем (в том же серверном скрипте) всплывающий аплет:

var oServiceAF = TheApplication().GetService("SLM Save List Service");
var inputPropAF = TheApplication().NewPropertySet();
var outputPropAF = TheApplication().NewPropertySet();
inputPropAF.SetProperty("Applet Name","FINS Accounts List Applet Report");
inputPropAF.SetProperty("Applet Mode","2"); //у нас form-аплет имеющй шабоны типа base и edit
inputPropAF.SetProperty("Applet Height", "700");
inputPropAF.SetProperty("Applet Width", "700");
oServiceAF.InvokeMethod("LoadPopupApplet", inputPropAF, outputPropAF);
outputPropAF=null;inputPropAF=null;oServiceAF=null;

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

var ctrl = this.FindControl("area");
ctrl.SetValue(TheApplication().GetProfileAttr("TextData"));
TheApplication().SetProfileAttr("TextData","");

где area это текстовое поле типа TextArea.

Чисто теоретически в бразуерном скрипте всплывающего аплета мы могли бы создать Excel COM-объект и на основе одной или более входящих строк сформировать читаемый отчёт в любом угодном нам виде.

Работа с mvg(multivalue group) полями. Связи между БК в пределах одного БО

Тут ещё очень много малопонятного поэтому к предоставленной информации следует относиться с осторожностью.

Основные положения:


  • МВГ-поля это такие поля в которых могут содержаться больше одного значения. Часто у таких полей одно из значений может считаться главным (основным) хотя это и не обязательно

  • Собственно БК для того и включаются в БО чтобы между ними могли быть установлены какие-то взаимосвязи. Поэтому теоретически достаточно в коде получить БО, потом БК1, найти нужную запись (SetSearchSpec)именно из этого БО и потом получив из того же БО другой БК2 надеяться, что мы уже выбрали какие-то записи БК2 для которых БК2.поле связи = БК1.поле связи. Однако это почему-то не всегда так.

  • отличие mvg-аплета от pick-аплета в том, что в первом можно выбрать много записей, а во второй только одну (правда из списка)

  • Собственно mvg-поля и повешенные на них mvg-аплеты это как раз тот механизм, с помощью которого можно сделать master-detail

Замечания о типах связей между БК в пределах одного БО (а других связей и не бывает)


  • Связь один ко многим(частный случай один к одному). Промежуточная таблица (Inter Table) не требуется. Для примера ниже связь идёт как Campaign List Contact.Id = Audit Trail Item 2.Record Id См

  • Многие ко многим (обязательно через промежуточную таблицу). Обратите внимание на то, что Destination Field для дочернего бк пусто

В самом бк Campaign имеется  следующая связь:
само поле описывается на бк Campaign так (то, что связь наз Organization и поле называется также простое совпадение)
Добавить одно значение (а там может храниться несколько) и сделать его основным я могу следующим кодом
oCampaign = TheApplication().GetBusObject("Campaign");

//пытаемся установить организацию для компании
if (InputParam_Org!=""){
var bcInternalDivision : BusComp =cCampaign.GetMVGBusComp("Organization").GetAssocBusComp();
bcInternalDivision.ClearToQuery();
bcInternalDivision.SetViewMode(AllView);
bcInternalDivision.SetSearchSpec("Name", InputParam_Org);
bcInternalDivision.ExecuteQuery(ForwardOnly);
if (bcInternalDivision.FirstRecord()){
bcInternalDivision.Associate(NewAfter);
}
else{
TheApplication().RaiseErrorText("Organization/Internal Division ("+InputParam_Org+") NOT FIND");
}
var InternalDivisionId=bcInternalDivision.GetFieldValue("Id");
cCampaign.ActivateField("Primary Organization Id");
cCampaign.SetFieldValue("Primary Organization Id", InternalDivisionId);
cCampaign.WriteRecord();
bcInternalDivision=null;
}

В вышеприведённом коде я для одной записи (если хотите для одного экземпляра) бк cCampaign беру его ассоциированный компонент Internal Division (потому, что именно на этот бк ссылается связь Organization нацепленная на поле Organization (я беру по полю используя метод GetMVGBusComp). Нахожу необходимую организацию (экземпляр бк Internal Division) и ассоциирую (привязываю) его к бк cCampaign, потом делаю новонайденную и новопривязанную организацию главной.

для красивого отображения на аплете (чтобы можно было заполнять мвг-поле значениями не только программно, но и из веб-интефейса)

Для простой навигации по mvg-дочернему компоненту достаточно

var bo = TheApplication().GetBusObject("Action");
var bc = bo.GetBusComp("Action");

bc.ActivateField("Activity Id");
bc.ClearToQuery();
bc.SetViewMode(AllView);
bc.SetSearchSpec("Activity Id", sActionId);
bc.ExecuteQuery(ForwardOnly);
bc.FirstRecord();
var bcMvg = bc.GetMVGBusComp("Product Line Interest for Activity Id");

var isRecord = bcMvg.FirstRecord();
while (isRecord)
{
var PrdLnId = bcMvg.GetFieldValue("Product Line Id");
isRecord = bcMvg.NextRecord();
}

Подробнее см

http://docs.oracle.com/cd/B40099_02/books/EAI2/EAI2_IntObjs_Understanding9.html

http://dream2real.weebly.com/uploads/6/1/3/9/6139766/32_config_multivalue_groups.pdf

Примечание: