admin 管理员组文章数量: 1184232
2024年3月12日发(作者:聚源广告联盟)
(结合视频教学资料使用)
1. UBF路径配置
(视频160)
2. 解决方案建立规则
目录层次:解决方案>>项目>>组件
同一模块,所有BE、BP、SV项目放在(同)一个解决方案内
同一模块,所有BE,只用一个项目,即只生成一个BE的DLL
同一模块,所有BP、SV,只用一个项目,即只生成一个BP、SV的DLL
同一模块,可以所有枚举放在(同)一个BE组件内
同一模块,所有UI项目放在一个解决方案内
一个档案或单据UI,及其相关的查找参照UI,用(同)一个项目,即一个档案或单据,生成一个UI的DLL
同一模块,所有列表UI,用(同)一个项目
同一模块,所有参照UI,用(同)一个项目
3. 命名规范
配件名:(地区).HXPP(公司).EX(模块)BE
表名:Cust_XM(地区)_HXPP(公司)_EX(模块)_XXXX
4. 档案开发需求
(视频170,180)
考核模块(EX)>>科目(Subject)
名称
Org
显示名称
组织
类型
组织机构
备注
业务主键,不可空
Code
Name
SubjectType
编码
科目名称
科目类型
字符串
字符串
科目类型枚举
业务主键,不可空,长50
不可空,长200
枚举值:辅料、主要材料、产值、费用,对
账差异,营销可比利润,调节项,其他收入,
税后利润,考核税前利润
长500
Effective
Memo
DescFlexField
状态
备注
扩展字段
状态
字符串
实体扩展字段集合
5. BE Code与Model对比
6. 组件、类实体、属性关系查询(SQL语句)
select a. Name as ComponentName ,at. DisplayName as ComponentName_CN,a. AssemblyName,a .Kind
,b. Name as ClassName , bt. DisplayName as ClassName_CN,b. FullName,b .Discriminator
,c. Name as AttributeName ,ct. DisplayName as AttributeName_CN
from UBF_MD_Component a
left outer join UBF_MD_Component_Trl at on a. Local_ID=at .Local_ID and lag= 'zh-cn'
left outer join UBF_MD_Class b on a. ID=b .MD_Component_ID
left outer join UBF_MD_Class_Trl bt on b. Local_ID=bt .Local_ID and lag= 'zh-cn'
left outer join UBF_MD_Attribute c on b. ID=c .MD_Class_ID
left outer join UBF_MD_Attribute_Trl ct on c. Local_ID=ct .Local_ID and lag= 'zh-cn'
where (1 =1)
and bt. DisplayName='科目'
7. UI Code与Model对比
8. UIForm、Part、Page的关系查询(SQL语句)
select at .DisplayName as UIFormDisplayName , a .name as UIFormName ,c. name as PageName
,a. uid as [UID(FormID)], de
,a. uri as [PartID(UIFormURI)], as PageURI
,a. AssemblyName , ame
,a. Width,a .Height, as ApplicationName
from ubf_md_uiform a
left outer join ubf_assemble_part b on =b. component
left outer join ubf_assemble_page c on =c. id
left outer join base_application_trl dt on ation =dt. id and dt. sysmlflag='zh-cn'
left outer join ubf_md_uiform_trl at on =at. id and at. sysmlflag='zh-cn'
where (1 =1)
and yName='科目'
9. 同步枚举脚本
以补丁包方式更新/安装,则不需要下面的脚本,因为be的bulk中会处理;
delete from ubf_sys_extenumtype
delete from ubf_sys_extenumtype_trl
delete from ubf_sys_extenumvalue
delete from ubf_sys_extenumvalue_trl
GO
insert into ubf_sys_extenumtype select local_id as id,'20060612' ,'u9zhangheng', '20060612','u9zhangheng' ,0, fullname as
code, isextend,id as uid,0 as IsRefView from ubf_md_class where classtype=3
insert into ubf_sys_extenumtype_trl select a .local_id as id ,'zh-CN', b.[displayname] as [name],b .[Description] from
ubf_md_class a left join ubf_RES_resourcevalue b on cast( a.[iD] as nvarchar(255 )) = b. resourcename where classtype =3
insert into ubf_sys_extenumvalue select a .local_id as id,'20060612' ,'u9zhangheng', '20060612','u9zhangheng' ,0,
a.[Local_Class_ID] as ExtEnumType , a.[name] as code,a .defaultvalue as evalue ,issystem, md_class_id as ExtEnumTypeUID
from ubf_md_attribute as a inner join ubf_md_class as b on a. md_class_id=b .id where classtype =3
insert into ubf_sys_extenumvalue_trl select a .local_id as id ,'zh-CN', c.[displayname] as [name] from ubf_md_attribute as a
inner join ubf_md_class as b on _class_id =b. id left join ubf_RES_resourcevalue c on cast( a.[ID] as nvarchar(255 )) = c.
resourcename where classtype= 3
GO
--枚举值表关系
SELECT a .Code , at .NAME ,a. EValue, AS EnumTypeUID FROM UBF_Sys_ExtEnumValue a
LEFT OUTER JOIN UBF_Sys_ExtEnumValue_Trl at ON =at . id AND at. SysMLFlag='zh-cn'
LEFT OUTER JOIN UBF_Sys_ExtEnumType c ON mType =c . id
WHERE c .Code = 'mTypeEnum'
10. 装配发布
(视频190)
Studio
,修改UILib路径
.
size=4096;Max Pool size=1500;persist security info=True
带实例名的ConnectionString
Catalog=hxpp0326;packet
Catalog=HXPP0145;packet size=4096;Max Pool size=100;Connection Timeout=900;persist security
info=True;MultipleActiveResultSets=true;
11. 常用代码
(视频200,210,220)
BE上赋默认值,OnSetDefaultValue 处增加代码
if ( == null)
{ = rg; }
UI上赋默认值,Model>>AfterInitModel 处增加代码
tValue = ;
rg_tValue = lumn;
rg_tValue = lumn;
扩展字段处理,在Webpart>>AfterCreateChildControls()里面调用:
cFlexField(eldPicker0, t);
其中:eldPicker0为要设置的描述性弹性域控件, t为描述性弹性域所在的 View,把Subject
换成你的 View就可以了。
复制,Webpark中按钮事件写代码,复制功能自动完成,增加清除不需复制值的代码即可
= ;
开启个性化,AfterCreateChildControls中加
sonalizationEnable(this, true);
删除按钮绑定提示,AfterCreateChildControls中加
lConfirmDialog(,eteConfir
mInfo(), "", ete);
弹出窗口与非弹出窗口的按钮控制(确定、取消),在AfterUIModelBinding中调用SetControlStauts
private void SetControlStauts ()
{
//是否为弹出模态窗口
if (eLink(this)
lPopup(this))
{
e = true;
e = true;
//列表动作不可用
d = false;
}
else
{
//确定取消不可见
e = false;
e = false;
d = true;
}
}
附件>>不用写代码,只需启用文档库。
12. UI事件的执行先后顺序
AfterEventBind,事件绑定之后
AfterCreateChildControls,创建控件之后
OnLoadData_Extend(刷新时执行,一般PostBack不执行)
AfterOnLoad
OnDataCollect_Extend(刷新时不执行,PostBack执行),数据收集
BeforeUIModelBinding,UIModel的值绑定到UIForm的控件之前
AfterUIModelBinding,UIModel的值绑定到UIForm的控件之后
||
13. 贯穿BE和UI的关系图
14. 不走审批流的提交、审核、弃审处理
不走审批流的提交、审核、弃审,按钮状态控制(示例代码)
private void SetControlStauts()
{
PrintProduceSituationRecord r1 = dRecord;
if (r1 != null)
{
switch ()
{
case 0:
d = true;
d = false;
d = false;
d = true;
ly = false;
break;
case 1:
d = false;
d = true;
d = false;
d = true;
ly = false;
break;
case 2:
d = false;
d = false;
d = true;
d = false;
ly = true;
break;
default:
break;
}
}
//控制只读
((ldBindingDataBindControl)178).ReadOnly = true;
((IUIFieldBindingDataBindControl)edBy101).ReadOnly = true;
((IUIFieldBindingDataBindControl)edOn311).ReadOnly = true;
}
不走审批流的提交、审核、弃审按钮处理(示例代码)
private void BtnSubmit_Click_Extend(object sender, EventArgs e)
{
PrintProduceSituationRecord r1 = dRecord;
if (r1 != null && == 0)
{
BtnSave_Click_Extend(sender, e);
= 1;
BtnSave_Click_Extend(sender, e);
SetControlStauts();
}
BtnSubmit_Click_DefaultImpl(sender, e);
}
private void BtnApprove_Click_Extend(object sender, EventArgs e)
{
PrintProduceSituationRecord r1 = dRecord;
if (r1 != null && == 1)
{
BtnSave_Click_Extend(sender, e);
= 2;
edBy = ();
edOn = ;
BtnSave_Click_Extend(sender, e);
SetControlStauts();
}
BtnApprove_Click_DefaultImpl(sender, e);
}
private void BtnUndoApprove_Click_Extend(object sender, EventArgs e)
{
PrintProduceSituationRecord r1 = dRecord;
if (r1 != null && == 2)
{
BtnSave_Click_Extend(sender, e);
= 0;
edBy = null;
edOn = null;
BtnSave_Click_Extend(sender, e);
SetControlStauts();
}
BtnUndoApprove_Click_DefaultImpl(sender, e);
}
15. 常用ContextItems(上下文值)
me
me
de
e
t
riseID
riseName
16. 查找代码
(视频230)
查找代码,AfterCreateChildControls中加
nfirmDialog(, "92afc0de-6cba-4b56-a815-5efd0f2ebb55", "580",
"408", Title, ID, BtnFind);
其中FormID,可在UI对应的Webpart代码中查到
17. 参照关系查询(aspnet_Parts,UIRComponent,UIReference,EntityReference,Class,Component)(SQL语句)
select a. FormId , a .ClassName as RefClassName ,a .Assembly as RefAssemblyName,a. URI as RefURI
,b. Name as RefComponentName ,bt. DisplayName as RefComponentName_CN
,c. RefType ,c .Name as RefTypeName,c .Filter, ityId ,c. RefEntityName
,d. MD_Class_ID as [EntityReference_ClassID] ,d. MD_Template_ID as [EntityReference_TemplateID]
,e. Name as RefEntity_ClassName ,e. FullName as RefEntity_ClassFullName, tTableName as RefEntity_TableName,et.
DisplayName as RefEntity_ClassName_CN
,f. Name as RefEntity_ComponentName ,f. AssemblyName as RefEntity_AssemblyName
from aspnet_Parts a
left outer join UBF_MD_UIRComponent b on a. FormId=b .UID
left outer join UBF_MD_UIRComponent_Trl bt on b. ID=bt .ID
left outer join UBF_MD_UIReference c on b. UID=c .Container
left outer join UBF_MD_EntityReference d on c. Container=d .MD_Template_ID
left outer join UBF_MD_Class e on c. RefEntityId=e .ID
left outer join UBF_MD_Class_Trl et on e. Local_ID=et .Local_ID
left outer join UBF_MD_Component f on e. MD_Component_ID=f .ID
where (1 =1)
and c. Name='cref'
and (et. DisplayName='科目')
18. 代码控制过滤条件
通过代码,给参照加过滤条件(示例代码), BeforeUIModelBinding
IUFFldReferenceColumn c1 = (IUFFldReferenceColumn)s["WaterMarkMO"];
InParams = _AddCustomFilter +
"=UFIDA::U9::Cust::HXPP::MO::WaterMarkMOBE:: in (select from UFIDA::U9::MO::MO::MO
as MO where =UFIDA::U9::Cust::HXPP::MO::WaterMarkMOBE:: and te in (2,3))";
用代码控制参数过滤(示例代码),Webpart,在OnLoadData_Extend中写代码
if (ters[0] != null)
{
//此处.Parameters[0],也可用.Parameters["@ID"]代替
long curID = (ters[0].ng());
if (curID > 0)
{
string childID = ildID("CustUT_GC_ParameterConfig", "Parent", curID);
if (!OrEmpty(childID))
{
+= " and UFIDA::U9::Cust::UT::GC::ParameterConfigBE::
not in (" + childID + ")";
}
}
}
19. 页面导航代码
(视频240)
卡片导航到列表,在相应的UI项目,Webpart,BtnList_Click_Extend
tePage("tListURI", null);
列表导航到卡片
新增,在相应的LIST Action,OnNew_Extend中加
tePage("tURI", null);
双击行跳转,在相应的LIST Action,OnGridRowDbClick_Extend中加
Paramter p = new NaviteParamter();
//是正拖的话,这里需用MainID
string dataid = dRecord["ID"].ToString();
if (!OrEmpty(dataid))
{
("PDPageStatus", "browser");
("ID", dataid);
tePage(tPart,
"tURI", p);
}
列表过滤当前组织数据,在相应的LIST Action,CustomFilterOpath_Extend中加
if (OrEmpty(filterOpath))
{ filterOpath = ("Org={0}", );
}
else
{ filterOpath += (" and Org={0}", );
}
20. 单据开发需求
费用明细单单据类型(继承单据类型基类)(FDDocType)
名称
IsPreset
费用明细单(继承单据基类)(FeeDetail)
名称
FDDocType
FeeType
Status
BadDebtAdd
BadDebtReduce
FundOccupancy
Memo
显示名称
组织
单据类型
单号
日期
费用类型
状态
坏账增加
坏账减少
资金占用额
备注
扩展字段
类型
费用明细单单据类型
费用类型枚举
(普通)单据状态枚举
十进制
十进制
十进制
字符串
备注
基类
不要用DocType,会与重载
方法重名
基类
基类
枚举值:暂估、准确
枚举值:开立、审核中、已
审核
精度2
精度2
精度2
长500
基类
显示名称
编码
名称
描述
系统预制
状态
上游单据推出
编号方式
编号规则
确认方式
审批方式
自动生成编号是否可改
类型
布尔
备注
基类
基类
基类
UI不显示
基类
基类
基类
基类,Form引用
基类
费用明细单行(FeeDetailLine)
名称
RowNo
Subject
Fee
Memo
DescFlexField
显示名称
行号
科目
费用
备注
扩展字段
类型
整数
科目
十进制
字符串
实体扩展字段集合
备注
精度2
长500
(视频250)
单据类型基类、单据基类,在发布对象浏览器的UBF的BaseBE内,DocTypeBE
(固定)编译出错:
错误 4 “ail”不会实现继承的抽象成员
“” D: 14 24
需要在BE代码对应单据(FeeDetail)的Extend中,增加以下代码
//重载
public override e DocType
{
get { return ype; }
}
//费用明细单单据类型,费用明细单,实体对应Extend,OnSetDefaultValue中赋组织默认值
赋默认值代码
21. 费用明细单单据类型UI开发
(视频260)
编号规则(又叫编码方案)的参照,在发布对象浏览器的UI的ta中
编号规则(又叫单据编码规则)的Form引用,在发布对象浏览器的UI的t
费用明细单单据类型查找对应的参照开发
常用代码
查找代码
发布组件、发布页面、发布菜单
22. 费用明细单单据类型列表对应开发
(视频270)
页面导航代码
发布页面
23. EX模块的参照开发(EXUIREF)
(视频280)
费用明细单单据类型参照
科目的参照
发布组件
24. 费用明细单UI开发
(视频290)
费用明细单查找对应的参照开发
发布组件、发布页面、发布菜单
加代码
(视频300)
常用代码
//默认当前日期,单据UI>>Model>> AfterInitModel
tValue = ;
//Grid上的扩展字段处理
cFlexField(id5, - 1, "DescFlexField");
//行号设置
//引用,
fileValueProxy p1 = new fileValueProxy();
int sequenceStart1 = 10;
owNo r1;
eCode = "SysLineNo";
eOrg = ();
ata data1 = ();
if (data1 != null && !OrEmpty(eValue))
{ se(eValue, out sequenceStart1); }
r1 = ((owNo)s["RowNo"]);
ce = true;
ceStart = sequenceStart1;
ceStep = ceStart;
查找代码
25. 费用明细单列表对应开发
(视频310)
页面导航代码
发布页面
26. 费用明细单中单据类型、及科目的Form引用实现
(视频320)
弹出Form,取消按钮关闭窗口代码
ialog(false);
27. BP开发
BP开发,假定需求:费用明细单,增加加载按钮,按传入条件自动加载行。
(视频330)
传入:组织ID,长整型;科目类型,整型
返回:List
需要引用:
28. BE,UI,BP,SV引用规则
必须按以下规则引用DLL
UI
,
,
(UI层严禁直接操作底层数据库,不能直接调BP、SV,必须通过代理调用)
BP
BE(本模块)
(跨模块)
BP(本)
SV(跨)
BE
【特殊情况】(本)
后期UI启用新事件,(由于Extend代码不会再覆盖)需手动在Extend中加事件代码,可参考原有的事件写,如
private void BtnClose_Click_Extend(object sender, EventArgs e)
{
BtnClose_Click_DefaultImpl(sender, e);
}
29. BP部份关键代码
BP代码
//实体查找,写法1
StringBuilder sb1=new StringBuilder (256);
("Org=@org1");
(" and SubjectType=@subjecttype1");
(" and ctive=1");
(" and '" + ateTime +"' between iveDate and eDate");
List el1 = l(ng(),new OqlParam [2]{new OqlParam
( ),new OqlParam (tTypeValue)});
UI代码
写获取行号的方法
//增加行前,先清除旧行
ail_();
//增加新行
FeeDetail_FeeDetailLineRecord r1 = ail_UIRecord();
//绑定父行
entRecord(dRecord);
30. 调试
代码调试(U9V2.5使用VS2005调试,需按以下修改)
1、修改U9应用程序池(运行inetmgr),将.Net Framework版本改为2.0
2、Portal下,原改名为>>(备份),35改为>>
(如按以上修改后,Portal无法正常打开,则还原上面的修改,安装VS2010 Ultimate,将要调试的类文件,拖入vs2010,
同样是附加到进程进行调试)
调试方法
将代码附加(快捷键Ctrl+Alt+P)到w3wp(勾选显示所有会话中的进程)进程,设置断点,即可进行调试。
异常控制(Ctrl+Alt+E):用于无法定位错误位置的代码调试。
快速监视(Ctrl+D、Q):查看变量值。
31. UI布局设计
通过对容器的网格行、列集合属性的设定,以及摆放各类控件,进行UI布局设计。
容器类控件均有“容器布局”属性,容器布局属性主要由上边距、下边距、左边距、右边距、行间距、网格列集合、
网格行集合属性组成,UIForm,Card(卡片控件)均为容器。
容器布局
容器内分布网格(网格列集合,网格行集合组成),网格存放各控件,Card的网格有类型value,spacing,title;
如上卡片控件(Card),网格列集合数为7,网格行集合数为8,灰色为行间距。
可以看布局列信息上面的末列数值,对快速布局很有帮助,末列数值指示出最后一列的宽度,如下:
多用界面控件树查看层次关系,有助于提升视觉理解。
练习画以下UIForm样式:
(视频340)
32. 建立主账簿(使标准产品不要进入即报错)
(视频350)
33. 插件开发
包括有UI插件、BE插件、BP插件,而其中的BP插件较少应用,可按需查阅用友开发资料。
命名规范依据项目而定,最重要是统一,参考如下:
UI插件命名空间、程序集名称、项目名称:.地区.客户. UIPlugIn
插件类命名:单据简称+UIPlugInExtend
BE插件命名空间、程序集名称、项目名称:.地区.客户.BEPlugIn
插件类命名:单据简称+[插件位置(Update、Insert……)可略,可通过Event判断]+BEPlugInExtend
34. UI插件开发
(视频360)
假定需求:在采购管理>>标准采购的下方操作功能区,增加“科目”按钮,弹出“科目”窗口,同时将标准采购的单
据类型名称,传给“科目”的备注,参考图:
35. UI插件开发过程关键点
手动新建类库项目(使生成代码命名风格与U9生成的代码保持一致);
//必须引用的dll
// (bin,applicationserverbin)
// (ubflib,applicationserverbin)
//页面扩展按钮必须引用的dll
// (bin,applicationserverbin)
// (bin,applicationserverbin)
//.NET的
// (bin,applicationserverbin)
// (ubflib,applicationserverbin)
//......
UI插件可扩展的事件(常用的)
初始化后,创建控件树,创建关联控件
AfterInit( part, EventArgs args)
Form加载后
AfterLoad( Part, EventArgs args)
......
扩展类示例代码(参考代码)
public class ExtendUIProcess : edPartBase
{
//后面事件需要通过IPart取值
private _part;
///
/// 重写初始化后事件,创建控件树,创建关联控件
///
///
///
public override void AfterInit( part, EventArgs args)
{
//首先调用原来的事件
nit(part, args);
//校验有效
if (part == null || == null)
{return;}
_part = part;
//页面扩展-加按钮
#region 页面扩展-加按钮
//实例化按钮
IUFButton btnShowSubject = new UFWebButtonAdapter();
= "科目";
= "BtnShowSubject";
stBack = true;
//加入Card容器
IUFCard card = (IUFCard)ontrolByName(elContainer, "Card0");
(btnShowSubject);
(card,btnShowSubject, 18, 0);
//设置按钮事件
+= new EventHandler(btnShowSubject_Click);
#endregion
}
}
//按钮事件
void btnShowSubject_Click(object sender, EventArgs e)
{
//写业务逻辑代码
//......
}
//集团人员写的类,可复制使用
public class CommonFunction
{
///
/// 设置控件在卡片容器中的布局
///
/// 卡片容器
/// 增加的控件
/// 布局横坐标
/// 布局纵坐标
public static void Layout(IContainer container, IUFControl ctrl, uint x, uint y)
{
Layout(container, ctrl, x, y, 1, 1, (0), (0), true);
}
///
/// 设置控件在卡片容器中的布局
///
/// 卡片容器
/// 增加的控件
/// 布局横坐标
/// 布局纵坐标
/// 控件宽
/// 控件高
public static void Layout(IContainer container, IUFControl ctrl, uint x, uint y, int width, int height)
{
Layout(container, ctrl, x, y, 1, 1, (width), (height), false);
}
///
/// 设置控件在卡片容器中的布局
///
/// 卡片容器
/// 增加的控件
/// 布局横坐标
/// 布局纵坐标
/// 单元格横向跨度
/// 单元格纵向跨度
/// 控件宽
/// 控件高
/// 是否自适应大小
public static void Layout(IContainer container, IUFControl ctrl, uint x, uint y, int xspan, int yspan,
Unit width, Unit height, bool isAutoSize)
{
IGridLayout gl = as IGridLayout;
if (gl == null) return;
GridLayoutInfo glInfo = new GridLayoutInfo((uint)x, (uint)y, (uint)xspan, (uint)yspan, width, height);
ze = isAutoSize;
((Control)ctrl, glInfo);
}
}
36. UI插件部署
UI插件配置文件说明(部署UI插件,先看看效果)
复制Portal WebPartExtend_文件,进行修改>>WebPartExtend_Cust_XM_HXPP_(标准模块).config 文件
extendedPartFullName="essExtend" extendedPartAssemblyName="">
(相应修改以下内容)
parentPartFullName 要扩展的原Form全名
extendedPartFullName 插件类全名
extendedPartAssemblyName 插件程序集名
如何查要扩展的原Form全名
UI插件部署位置
UI插件dll部署到 portaluilib(可自行编写)
WebPartExtend_ 部署到 portal
37. 按钮事件代码参考
//将插件中的FocusedReocrd转成强类型,以方便取值,具体Record所在的View,可使用监视查看
//引用
seOrderRecord r1 =
(seOrderRecord)_[0].FocusedRecord;
lueCollection p1 = new lueCollection();
("PODocTypeName",ntType_Name);
//弹出科目窗口,cd989ec3-fe4e-4943-8e4c-a2f91a5d1bab为FormID,可打开源代码查看,也可通过sql语句查看
//p1为NameValueCollection,页面传参用
_dalDialog("cd989ec3-fe4e-4943-8e4c-a2f91a5d1bab", "科目", "992", "504", _ng(), p1,false);
//科目页面,接受参数值处理
public void BeforeUIModelBinding()
{
if (dRecord == null)
{ dRecord = UIRecord(); }
if (NameValues != null && NameValues["PODocTypeName"] != null)
{
= NameValues["PODocTypeName"].ToString();
}
}
38. UI插件常用代码(示例代码)
//取得插件页面上的按钮控件
ton btnSetup = (IUFButton)_ontrolByName(this._elContainer,
"BtnSetup");
//注册按钮事件
+= new EventHandler(btnSetup_Click);
//编写按钮事件动作代码
void btnSetup_Click(object sender, EventArgs e)
{}
//NameValue页面传值
//传送
//引用
seOrderRecord r1
(seOrderRecord)_[0].FocusedRecord;
lueCollection p1 =
lueCollection();
("PODocTypeName",ntType_Name);
_dalDialog("cd989ec3-fe4e-4943-8e4c-a2f91a5d1bab", "科目", "992",
_ng(), p1,false);
//接收
if (NameValues != null && NameValues["PODocTypeName"] != null)
{
= NameValues["PODocTypeName"].ToString();
}
//CurrentState页面传值
//传送
//引用
seOrderRecord r1
(seOrderRecord)_[0].FocusedRecord;
//需引用
_tState["POBusinessDate"] = ssDate;
//接收
if (tState["POBusinessDate"]!=null)
{
= tState["POBusinessDate"].ToString();
tState["POBusinessDate"] = null;
}
//……
39. 扩展字段的配置与使用
(视频370)
实体
料品
扩展字展
类型
备注
=
new
"504",
=
料号、品名配置为手工录入型,不使用弹性域功能
编码,字符型,长度50
名称,字符型,长度200
0~10000,全局段,也叫私有段
0~10000
0~10000
料品
料品
请购单行
全局扩展字段1,克重起
全局扩展字段2,克重止
全局扩展字段1,克重
整型
整型
整型
按以上表格要求配置,能成功保存请购单,为后面的BE插件开发做准备。
40. BE插件开发
(视频380)
假定需求:(前面对料品、请购单行增加了扩展字段)开发BE插件,在(标准产品)请购单保存前进行校验(可在如
Validate事件中校验),校验请购单行的“克重”(全局段1)必须在料品的“克重起”与“克重止”范围内,否则抛出
异常提示。
41. BE插件可插入的事件及事件顺序
新增
BeforeDefaultValue>>SetDefaultValue>>AfterDefaultValue>>BeforeValidate>>Validate>>AfterValidate>>BeforeInserting>>Inse
rting>>AfterInserting>>BeforeInserted>>Inserted>>AfterInserted
修改
BeforeDefaultValue>>SetDefaultValue>>AfterDefaultValue>>BeforeValidate>>Validate>>AfterValidate>>BeforeUpdating>>Upd
ating>>AfterUpdating>>BeforeUpdated>>Updated>>AfterUpdated
删除
BeforeDeleting>>Deleting>>AfterDeleting>>BeforeDeleted>>Deleted>>AfterDeleted
42. BE插件扩展类继承
/*必需引用
(bin,applicationserverbin)
(bin,applicationserverbin)
(bin,applicationserverbin)
(bin,applicationserverbin)
(applicationserverlibs)
(applicationserverlibs)
类必须继承 Subscriber 接口
内含Notify方法(IEventSubscriber 成员):
public void Notify(params object[] args)
**/
43. BE插件扩展类示例
[st]
public class CompleteRpt_Approving : Subscriber
{
#region IEventSubscriber 成员
public void Notify(params object[] args)
{
#region 从事件参数中取得当前业务实体
//判断入口参数的有效性(是否为我们需要进行插件处理的东东)
if (args == null || == 0 || !(args[0] is Event))
return;
//将入口参数列表中第一个参数,转成EntityEvent,并取EntityKey存入key
Key key = ((Event)args[0]).EntityKey;
//key的有效性判断
if (key == null)
return;
//转成所需实体,同时判断有效性
teRpt completeRpt = ity() as teRpt;
if (completeRpt == null)
return;
#endregion
//判断当前的BE事件(一个类,可以写多件BE事件的插件处理)
if (((Event)(args[0])).ns("Validate"))
{
//业务逻辑代码
//......
}
}
#endregion
}
查找实体的相关信息
44. BE插件配置文件示例
配置文件名:装配件名.
内容
说明
event:要扩展的BE事件,如Validate,Inserting等,格式:实体全名.事件名;
type:插件类,插件程序集;
subcription:可多个subcription,支持同一插件程序集,插入不同插件类于不同的BE事件;
45. BE插件部署位置
(先看看效果,看看是否能跳入BE插件的代码)
装配件(DLL文件)部署到PortalApplicationServerLibs
xml部署到Portalbin
46. BE插件业务逻辑代码参考
//查找料品
ster itemmaster1
ID();
if (itemmaster1 == null) { return; }
//扩展字段无值时,不进行校验(空串,用会出错,需另外处理)(视频430)
if (OrEmpty(eDescSeg1) ||
OrEmpty(eDescSeg1) ||
OrEmpty(eDescSeg2))
{ return; }
//请购单行的克重
int weight1 = (eDescSeg1);
//料品的克重起
int weightS = (eDescSeg1);
//料品的克重止
int weightE = (eDescSeg2);
//校验
if (weight1 < weightS || weight1 > weightE)
{
=
throw new Exception("行号:" + eNo + ", 录入的克重超出该料品对应的克重范围"
+ eDescSeg1 + "~" + eDescSeg2 + ",请检查");
}
47. 补丁包的制作
(视频390)
使用补丁包制作工具(BuildTool)实现。
48. 补丁包制作工具(首次)配置
将补丁包制作所需的数据库还原到现有的sql server内(U9BuildSp3);
修改;
修改;
U9 Portal的上一级目录路径
构造完成生成文件夹的路径
生成的补丁包(模块)显示文件名
修改;
工具的路径
49. 补丁包制作步骤
双击运行程序
新建方案>>输入方案名称(如Cust_XM_HXPP_EX )>>确定
选定方案>>构造>>没有Bom可构造,只创建输出目录>>确定
自动生成以下补丁文件夹结构
50. 文件放置说明
AssemblyInfo
放置,此文件是各个模块装配文件的集合。
Files
放置所有需要拷贝的文件,包括所有dll,插件及其xml。
Metadata
放置与原数据脚本一起生成的bulk文件。
PostSQL
放置执行完元数据脚本后执行的脚本。
PreSQL
放置需要预先执行的脚本。
ReportMD
放置报表模型和打印模型。
所有报表xml混合放在一起,不要建立子文件夹存放不同模型,属于数据库升级
(构造生成的建表脚本不需要放入补丁包中)
51. 补丁生成
(后续同一模块,更新补丁,执行这三步即可)
文件放置完成后->生成安装信息>>生成补丁。
52. 补丁包的安装
(视频400)
进入管理控制台>>(补丁参数设置,去掉备份数据库的勾选)>>(站点管理,添加补丁服务器)>>补丁丁载>>导入,
添加客开补丁>>安装。
53. DataCommand报表开发入门
(视频410)
假定需求:
标题:请购单统计表
查询条件(报表参数):组织,日期
数据来源:请购单
栏目:
(组织)、单据类型、单号、状态、日期、料号、品名、需求数量、核准数量、(交易)单位、要求交货日期、克重、
克重起、克重止、克重占比(=当前克重/查询结果克重之和*100%)。
参考画面:
54. DataCommand报表开发操作步骤
(PS:报表开发是一个需要反复地修改查看,查看修改的工作)
1、 新建空白报表
进入UBF,切换为:报表打印个性化模式。
菜单,文件>>登录,数据库服务器>>连接报表元数据库。
在报表资源管理中,建立自己的报表目录、报表容器、报表>>双击打开空白报表。
2、 生成DataCommand代码
菜单,报表>>Datacommand工具集>>Datacommand代码生成。
输入服务组名称(Datacommand Dll的中间段命名),生成路径(自动会再生成一个Report目录)。
Datacommand模型,在下次修改时,可选择以进行字段修改。
下一步,选择实体字段,将可以从实体中取选择的字段,全部勾选好(如单据,则以单据行为主驱动实体,进行勾
选),这一操作的目的,是把基础数据全部选好,涉及计算的字段、无法选取的字段,则需要通过代码手动加入。
勾选了报表参数,则后面在UBF设计中,可以在菜单,报表>>报表参数中直接看到,并且可以再修改。
下一步,输入Datacommand信息,Datasource命名以Ds结尾,Datacommand命名以Cmd结尾。
下一步,信息确认,保存Datacomand模型名称,以便下次可以修改,模型是一个xml文件,挂在Datacommand
代码的ReportParams内。
3、 DataCommand代码简释
//-----------------------------------
//临时表名定义部份
private const string BaseTempTable = "BaseTempTable";
//-----------------------------------
//报表参数对应实体字段(导入数据源后有报表参数配置,再追加此代码)
private Hashtable GetReportParameter()
{
Hashtable h1 = new Hashtable();
("PR_Org", "");
("PR_BusinessDate", "ssDate");
return h1;
}
//-----------------------------------
//业务逻辑处理部分,ProcessData中写代码
//调试时查看临时表内容用
t ds1 = null;
//从DS(数据源)中选取字段,为了拼基础表,这里是AllSelectFieldList
foreach (string field in ectFieldList)
{ ect(field); }
//取得报表参数Hashtable(导入数据源后,带出报表参数后,再加此代码)
Hashtable h1 = GetReportParameter();
//根据报表参数(过滤条件),过滤数据
foreach (IQueryParameter p1 in ters)
{
if (("ShowMode"))
{ continue; }
else
{ dition(h1[].ToString(), pe, or, ); }
}
//这个oql 是翻译不通过的
= String();
//但可以存在临时表里(内部有机制 ?)
TempTableByOql(BaseTempTable, , ery);
//调试时查看datatable内容
//ds1 = pTableDataSetByOql(, ery);
//基础表完成,开始基于基础表进行处理
//取查询结果克重之和,可以用idatareader,也可以用datatable(用case处理扩展字段为空串,
视频440)
long gramWeightTotal1 = 0;
eader idr1 = eDataReader("select
sum(convert(decimal(24,9),(case when isnull(exSegments_PrivateDescSeg1,'')='' then 0 else
exSegments_PrivateDescSeg1 end) )) from " + BaseTempTable + " as base", ery);
();
if (ount > 0 && idr1[0] != null && idr1[0] != )
{
gramWeightTotal1 = 64(idr1[0]);
}
();
e();
SimpleOqlTool sot1 = new SimpleOqlTool();
//设定from 语句
StringBuilder fromSb = new StringBuilder(256);
(BaseTempTable + " as base");
mClause(ng());
//个别字段进行处理,注意这次是从SelectFields中取,即用户所勾选择的栏目中取
foreach (string field in Fields)
{
//状态枚举,转成文字显示
if (("PR_Status"))
{ ect("GetEnumName('usEnum',_Status)", field); }
//克重,将请购单行的扩展字段1,转成十进制
else if (("GramWeight"))
{ ect("convert(decimal(24,9),(case when
isnull(exSegments_PrivateDescSeg1,'')='' then 0 else exSegments_PrivateDescSeg1 end ) )", field); }
//克重起,将料品的私有段1,转成十进制
else if (("GramWeightS"))
{ ect("convert(decimal(24,9),(case when
isnull(exField_PrivateDescSeg1,'')='' then 0 else exField_PrivateDescSeg1 end ) )", field); }
//克重止,将料品的私有段2,转成十进制
else if (("GramWeightE"))
{ ect("convert(decimal(24,9),(case when
isnull(exField_PrivateDescSeg2,'')='' then 0 else exField_PrivateDescSeg2 end) )", field); }
//克重占比,=当前克重/查询结果克重之和*100%)
else if (("GramWeightRate"))
{
//除以0处理
if ((0))
{ ect("0", field); }
else
{ ect("convert(decimal(24,9),(case when
isnull(exSegments_PrivateDescSeg1,'')='' then 0 else exSegments_PrivateDescSeg1 end ) )/" +
gramWeightTotal1, field); }
}
else
{ ect("base." + field); }
}
//结果oql 返回
= String();
//调试时查看datatable内容
//ds1 = pTableDataSetByOql(, ery);
ResultOqlString = ;
//-----------------------------------
//临时表定义部分
//转成文字显示
new Column("PR_Status", "nvarchar(50)"),
//隐藏这几个文字扩展字段
//new Column("DescFlexSegments_PrivateDescSeg1", "nvarchar(1000)"),
//new Column("DescFlexField_PrivateDescSeg1", "nvarchar(1000)"),
//new Column("DescFlexField_PrivateDescSeg2", "nvarchar(1000)"),
//增加克重字段
new Column ("GramWeight","decimal(24,9)"),
new Column ("GramWeightS","decimal(24,9)"),
new Column ("GramWeightE","decimal(24,9)"),
new Column ("GramWeightRate","decimal(24,9)"),
4、 部署DataCommand DLL
需要将DataCommand的dll复制到以下路径:
UBF的Runtime目录
StudioRuntime
Report Server的服务目录(可通过ReportingServicesService进程打开所在的目录位置)
Microsoft SQL 2012Reporting ServicesReportServerbin
(写批处理时,带空格的文件夹,前后需加上双引号)
手动增加CodeGroup节点:修改Microsoft SQL 2012Reporting
文件,复制CodeGroup节点,并追加到CodeGroup节点的末尾,复制后,只
修改下面标记灰色的位置,修改为你的DataComamnd Dll名称,如下参考(注意下面的CodeGroup段不能直接复制
到你的CodeGroup段内,而需要从你的报表服务器的CodeGroup中复制出来修改):
Description="Code group for u9 report data process extension1"> ">
CodeGroup增加完成后,请重启Reporting Services服务。
5、 导入DataCommand数据源
回到UBF报表设计环境>>菜单,报表>>导入>>DataCommand。
如导入后无任何字段,则表示出错,可通过查看消息列表进行排错。
注意:64位系统导入报表失败:调用的目标发生了异常,需要手动更新UBF 64位的几个文件。
导入数据源后,修改报表参数(过滤条件),并增加过滤条件代码。
(自己做一个组织参照,只能参照当前用户所属组织,过滤条件参考)
UFIDA::U9::Base::Organization::ctive=1 and '#me#' between
UFIDA::U9::Base::Organization::iveDate and
UFIDA::U9::Base::Organization::eDate and UFIDA::U9::Base::Organization:: in
(select Org from UFIDA::U9::Base::UserRole::UserOrg where User='##')
6、 报表UI设计
按项目组要求统一即可,如坐标、字体、颜色、对齐方式、显示格式等;
标题行颜色(230, 230, 230);小计行颜色(255, 244, 171)。
7、 发布报表
UBF>>报表资源管理器>>某张报表的报表容器,右键>>发布应用>>登录组织>>勾选删除用户方案>>下一步>>菜单发
布,如图,建立叶级菜单,绑定菜单,下一步>>执行>>下一步>>完成。
8、 查看效果
登入<
查看效果后,再根据效果,修改各个字段的属性,如类型、格式等。
9、 维护修改
修改DataCommand的代码,复制到相应目录内即可;修改报表样式,只需保存即可,不需再发布。
10、 出补丁包(报表的补丁包非全自动处理,需加上人为手动处理)
导出ReportMD:右键单击报表容器>>导出,放入补丁包的ReportMD;
(使用工具)手动导出菜单脚本:UBF_Assemble_Menu、UBF_Assemble_Menu_Trl,脚本可放入补丁包(PostSQL
文件夹内),注意一级、二级菜单均要导出脚本(视频450);
在报表服务器中,手动增加CodeGroup节点;
在报表服务器中,手动复制DataCommand Dll;
11、 其他说明
标题显示,用户自定义报表的修改>>菜单,报表>>报表属性>>文档信息>>模板描述。
报表代码调试:附加到ReportingServicesService进程(两个选项均勾选)。
当栏目字段拖入到“表”内时,显示格式则以“表”对应的报表属性为准,这时不以栏目的扩展属性为准了。
每次重新导入数据源,报表参数会自动增加一个“ShowMode”,需要手动删除。
55. 报表处理策略开发入门
(视频420)
策略是处于报表数据源、报表展现界面之间的一层代码结构。
策略的功能:
1、 调整模版
2、 设置查询方案的默认值:当前登录组织、日期、统计期间等
3、 对输入条件的验证:条件的合法性验证、相对非空验证
4、 对复杂条件的控制:相对值查询功能,比如今天、明天、上月、本月等
5、 对钻取动作的设置
假定需求:
使用策略,控制《请购单统计表》的报表参数(过滤条件),组织默认为当前组织。
报表策略开发操作步骤
1、 手动新建项目类,继承ReportProcessStrategy,命名规则参考
2、 需要引用的DLL
/*StudioRuntime
"" "" ""
"" "" "" ""
"" ""
*
* "" ""
"" "" ""
""
*
* "" ""
"" "" ""
""
*/
3、 集团示例代码
///
/// 重写 ProcessCaseDefine方法
/// 处理条件项定义信息:参数赋默认值、调整参照、弹性域处理
///
///
///
///
public override fine ProcessCaseDefine(
usercase, fine caseDefine)
{
caseDefine = sCaseDefine(usercase, caseDefine);
#region 集团示例代码
////组织赋默认值
//aultValue(
// ectByName("LogisticOrg_Code"),
//lumn,
// lumn,
//);
#endregion
return caseDefine;
}
4、 修改报表属性
策略类型全称:策略类命名空间与类名称组合,如 rtProcessStrategy
策略程序集:策略项目生成的dll名称,如 gy
5、 策略文件部署
策略文件部署到文件夹:U9PortalUILib
56. 打印开发入门
(视频460)
假定需求:
开发费用明细单的打印输出功能。
样式参考:
1、 UBF开发模式下,新建分析项目>>把urdl文件删除,添加一张报表
2、 打开设计区域的数据页签,新建数据源,设置数据查询
这一步的作用,仅仅是为了提供“字段名称”给打印模版进行设计用,真正的数据源还是在代码中拼取出来;
如果提供者类型是BusinessEntity,则设置实体关系时,选上第一行左关联实体即为主实体。
3、 打开布局页签,进行打印模版的设计
拖放表格控件到明细区,需要的字段拖放到表格上,就建立起了数据查询与表格控件的绑定关系;
设置布局属性,外观属性,数据属性。
4、 发布模版
菜单,报表>>发布到>>打印模型>>新建发布路径(打印分类目录),如(HXPP>>EX>>FeeDetail,FeeDetail为最末级)
最末一级打印分类目录,一定要设定“实体Key”,建议用实体全名以保证唯一,下一步后,右键单击表格,新建一个
打印模型容器,再下一步,打印模型发布。
5、 创建打印参照(参照打印模版)
菜单,报表>>模型元数据管理>>连接打印元数据库;
右键单击最末级分类目录(如FeeDetail)>>创建打印参照>>右击相对应的打印模版>>创建打印参照,其中生成Sql脚本,
用于制作补丁包时,放入PostSQL文件夹内;
复制打印模版的标识符(后面代码需要用):左边树选中打印模型容器,右边选中打印模型,点击编辑,复制该标识符。
6、 打印数据-扩展打印事件代码
打印代码*中写
private void PrintClick_Extend(object sender, UIActionEventArgs e)
{
tSettings settings =
tance().CreateExportSettingsObject();
//最末一级分类目录的实体Key
emplateCatalogType = "ail";
taCallBack = new DataCallBackHandle(ntData);
= settings;
//调用模版定义的默认实现方法.如需扩展,请直接在此编程.
lick_DefaultImpl(sender, e);
}
为不同打印模版准备不同数据
public void GetPrintData(object sender, DataCallBackEventArgs args)
{
DataSet returnDataSet = null;
switch (emplateID)
{
//费用明细单打印
case "c67698e9-bcef-43e3-afd2-066e0d208150":
{ returnDataSet = DetailData(); }
break;
default:
break;
}
Data = returnDataSet;
}
可以从当前的UIModel取数
private DataSet GetFeeDetailData()
{
DataSet returnDataSet = new DataSet();
DataTable tableTest = new DataTable();
("FeeDetail_DocNo");
("FeeDetail_BusinessDate");
("FeeDetail_FeeType");
("FeeDetail_Memo");
("FeeDetail_FeeDetailLine_RowNo");
("FeeDetail_FeeDetailLine_Subject_Code");
("FeeDetail_FeeDetailLine_Subject_Name");
("FeeDetail_FeeDetailLine_Fee");
("FeeDetail_FeeDetailLine_Memo");
FeeDetailRecord header = dRecord;
foreach (FeeDetail_FeeDetailLineRecord record in ail_s)
{
DataRow row = ();
row["FeeDetail_DocNo"] = ;
row["FeeDetail_BusinessDate"] = ssDate;
//获取枚举值,可以用BP,可以用case语句,未详细研究,这里先用case
switch (e)
{
case 0:
row["FeeDetail_FeeType"] = "暂估";
break;
case 1:
row["FeeDetail_FeeType"] = "准确";
break;
default:
break;
}
row["FeeDetail_Memo"] = ;
row["FeeDetail_FeeDetailLine_RowNo"] = ;
row["FeeDetail_FeeDetailLine_Subject_Code"] = t_Code;
row["FeeDetail_FeeDetailLine_Subject_Name"] = t_Name;
row["FeeDetail_FeeDetailLine_Fee"] = ;
row["FeeDetail_FeeDetailLine_Memo"] = ;
(row);
}
(tableTest);
return returnDataSet;
}
7、 其他说明
如果没有打印机,点击打印时,弹出IE窗口后,马上消失的话,需要安装PDF阅读软件才能正常预览。
在UBF开发模式下,修改打印模版,需要发布才能看到效果;而在UBF报表打印个性化模式下,修改打印模版,直接
保存后可以看到效果。
打印功能在实际项目中,多为套打的实现,需要连接打印机,直接打印出来调试位置。
输出点确定后画面消失,需要配置可信站点启用下载:Internet选项->安全->可信站点->自定义安全级别->下载分组,选
项“文件下载”、“文件下载的自动提示”,都设置为启用。
57. 参数设置
(视频470)
在标准产品中增加我们客开所需的参数,使用时可通过BP(UI中调fileValueProxy,
BP中调fileValue)读取,如下图。
(假定需求:增加一条参数设定,可设定费用明细单加载数据时的最大加载记录数。)
参数是通过脚本进行预置的。
表结构分析:
Base_Profile
字段
ID
CreatedOn
CreatedBy
ModifiedOn
ModifiedBy
ProfileValueType
SubTypeName
DefaultValue
Application
ControlScope
类型
bigint
datetime
nvarchar
datetime
nvarchar
int
nvarchar
nvarchar
bigint
int
说明
-
创建时间
创建人
-
-
参数值类型
子类型名称
缺省值
所属应用
作用范围
备注
0string 1int 2decimal 3bool 4date 6enum 7entity
当ProfileValueType=7时,此处填入实体名称,如
zation(组织机构)
0站点1组织2角色3用户4实体角色
SensitiveType
SysVersion
Code
ShortName
ValidateSV
CanBeUpdatedSV
UpdatedProcessSV
ReferenceID
Sort
Hidden
ShowPecent
IsSend
IsModify
Base_Profile_Trl
字段
ID
SysMLFlag
ProfileGroup
Name
Description
int
bigint
nvarchar
nvarchar
nvarchar
nvarchar
nvarchar
nvarchar
int
bit
bit
bit
bit
敏感性类型
-
参数编码
-
-
-
-
参照ID
-
-
-
-
-
0厂商修改1设置后不可改2使用后不可改3可追
朔修改4可前向修改
未知
类型
bigint
nvarchar
nvarchar
nvarchar
nvarchar
说明
-
语言标识
参数分组
参数名称
描述
备注
zh-cn中文
第一步,先Insert到数据库
declare @SNIndex bigint
if object_id('InnerAllocSerials') is null
exec [dbo].[AllocSerials]
@AllocCount = 20000,
@StartSN = @SNIndex output
else
exec [dbo].[InnerAllocSerials]
@AllocCount = 20000,
@StartSN = @SNIndex output
set @SNIndex=@SNIndex+1
--select * from base_application_trl where name='销售管理'
declare @CreatedBy nvarchar(50)='Peter'
declare @Application bigint=3015
declare @code nvarchar(200)
set @code='FeeDetailLineLoadRecordCountLimited'
--先delete
delete from Base_ProfileValue where Profile =(select ID from Base_Profile where Code=@code )
delete from Base_Profile_Trl where ID = (select ID from Base_Profile where Code=@code )
delete from Base_Profile where Code=@code
--再insert
INSERT INTO Base_Profile
(ID, CreatedOn, CreatedBy,
ModifiedOn,ModifiedBy,ProfileValueType,SubTypeName,DefaultValue,Code,[Application],ControlScope,SensitiveType ,Referen
ceID)
VALUES
(@SNIndex ,GETDATE(),@CreatedBy ,NULL,NULL ,1,NULL,'3',@code,@Application ,1,4,null)
INSERT INTO Base_Profile_Trl
(SysMLFlag,ID, [Description],[Name],ProfileGroup)
VALUES
('zh-CN',@SNIndex,'费用明细单加载记录数限制','费用明细单加载记录数限制','客开参数')
--多条参数时,@ID自增
set @SNIndex=@SNIndex+1
第二步,(使用脚本生成工具)导出来存为脚本(放在补丁包PostSQL内)
--参数预置,费用明细单加载记录数限制
if not exists (select 1 from Base_Profile where Code='FeeDetailLineLoadRecordCountLimited')
insert into [base_profile]
([ID],[CreatedOn],[CreatedBy],[ModifiedOn],[ModifiedBy],[ProfileValueType],[SubTypeName],[DefaultValue],[Application],[Con
trolScope],[SensitiveType],[SysVersion],[Code],[ShortName],[ValidateSV],[CanBeUpdatedSV],[UpdatedProcessSV],[ReferenceID
],[Sort],[Hidden],[ShowPecent],[IsSend],[IsModify]) values (1001,'2014-05-04
23:40:21',N'Peter',NULL,NULL,1,NULL,N'3',3015,1,4,0,N'FeeDetailLineLoadRecordCountLimited',NULL,NULL,NULL,NULL,NULL,
0,0,0,0,0)
if not exists (select 1 from Base_Profile_Trl where ID = (select ID from Base_Profile where
Code='FeeDetailLineLoadRecordCountLimited'))
insert into [base_profile_trl] ([ID],[SysMLFlag],[ProfileGroup],[Name],[Description]) values (1001,N'zh-CN',N'
客开参数',N'费用明细单加载记录数限制',N'费用明细单加载记录数限制')
UI加代码控制加载记录数(参考代码)
///
/// 获取加载行限制数的方法
///
///
private int GetLoadRecordLimited()
{
fileValueProxy p1 = new
fileValueProxy();
int limited1 = 3;
eCode = "FeeDetailLineLoadRecordCountLimited";
eOrg = ();
ata data1 = ();
if (data1 != null && !OrEmpty(eValue))
{ se(eValue, out limited1); }
return limited1;
}
//加载事件中,代码控制
//循环加载前,先读取限制数
//加载行数限制
int limited1 = GetLoadRecordLimited();
//......
//循环内结尾处进行判断(限制零加载时可如何处理?)
//限制数到达
limited1--;
if (limited1 <= 0) { break; }
58. 工作流开发
待写。
59. Profiler(SQL事件探查器)的使用
(视频480)
模拟跟踪场景:一张报表的查询过程,使用了哪些语句(如请购单统计表)。
用于跟踪数据库执行了什么语句,经常用在U9系统的执行情况跟踪。
运行Profiler,或者点击Performance Tool>>SQL Server Profiler。
Events Selection可选择跟踪的事件,多数我们所需的SQL语句,均在TSQL事件中。
Column Filters可设定对跟踪结果进行指定条件的筛选,如TextData>>Like>>%select%。
勾选Show all columns后,加上Column Filters功能,可对指定DB进行跟踪,通过DataBaseID>>Equals>>XX(XX为
DB的ID,可通过print db_id('hxpp0415') 这条语句获取。
在需要跟踪的动作发生前,先暂停跟踪,待一切准备就绪,则启动跟踪,并执行动作。
(请尝试跟踪一下,报表的查询方案保存在哪个表?)
60. 反编译BP/SV,并跟踪调试
(视频490)
使用.Net Reflector反编译DLL代码,使用VS进行跟踪。
将.Net Reflector集成到VS内:打开Reflector>>菜单,Tools>>Visual Studio and Windows Explorer Integration…>>勾选
Visual Studio 2005。
打开VS项目,菜单,.Net Reflector>>Choose Assemblies to Debug…(选择DLL反编译并调试)
如出现:Turn off "Enable Just My Code" in Visual Studio to start,则按此操作,菜单,工具>>选项>>调试>>取消勾选,
启用“仅我的代码”(仅限托管)。
Browse…需要踪踪的DLL,如:。
菜单,.Net Reflector>>Explore Decompiled Assemblies>>寻找BP及需要跟踪的类,双击将CS文件带到工作区。
如果需要跟踪已引用的其它类,可以打开对象浏览器(Ctrl+W,J),右击类>>Go to Decompiled Definition。
BP需要跟踪XXXImplementStrategy代码,所以需要在.cs文件的页签上按右键>>打开所在的文件夹,拖入
XXXImplementStrategy类文件。
找到Do()方法,设定断点,打开Portal,附加到进程。
61. 批处理
(主要讲解)
DOS批处理:是基于DOS命令的,用来自动地批量地执行DOS命令以实现特定操作的脚本。
扩展名,.bat;可以用notepad编辑。
关键字
echo
@
echo off
rem
功能说明
输出要显示的信息
@后面的的命令不显示出来
echo off下面所有执行的命令都不显示出来
注释
pause
if
goto
.
..
set
%X%
>
call
start
for
程序先挂起(暂停),按任意键继续
if 表示将判断是否符合规定的条件,从而决定执行不同的
命令
跳转到标签,goto XXX,:XXX
表示当前目录
表示上一级目录
设置环境变量,有参数使用
取变量X的值
输出通道,一般不输出结果可用>nul
从一个批处理程序调用另一个批处理程序,并且不终止父
批处理程序
调用外部程序,有参数使用
循环处理,支持多种复杂循环
62. 存储过程入门
一个最简单的存储过程
--procedure存在先删除,再创建
if exists ( select 1 from sysobjects where id=object_id (N'[dbo].[ProcedureName]' ) and objectproperty(id ,N'isprocedure' )=1 )
drop procedure ProcedureName
go
create procedure procedurename
@parameter nvarchar(50)=null
as
begin
print @parameter + ' ^ ^ '
end
go
创建临时表的方法
create table #temp1
(
Name nvarchar(50) null
,RecordCount bigint null
)
select ,,ttype, into #temp1
from Cust_XM_HXPP_EX_Subject a
left outer join Base_Organization b on =
where ='010'
if与exec语句
if (@parameter is not null)
begin
set @parameter='select ''' +@parameter + ' ^^''' +' as Parameter'
--select 'Parameter ^^' as Parameter
exec (@parameter)
return
end
游标的使用
declare @code1 nvarchar(50)
declare @name1 nvarchar(50)
--通过游标循环赋值给SQL变量
--定义游标
Declare cursor1 Cursor for
select ,
from Cust_XM_HXPP_EX_Subject a
left outer join Base_Organization b on =
where ='010'
--打开游标
Open cursor1
--打开游标后,指针指在第一条记录之前
--定位游标记录,并赋值入变量
Fetch next from cursor1 into @code1, @name1
--开始循环操作
While @@fetch_status=0
Begin
--写业务逻辑
print @code1 + ',' + @name1
--定位下一条记录,并赋值
Fetch next from cursor1 into @code1,@name1
End
--关闭游标
Close cursor1
Deallocate cursor1
一些信息表
--information_schema系列表
Select * from information_ where table_type='base table'
select * from INFORMATION_S where TABLE_NAME='cust_xm_hxpp_ex_subject'
示例及练习存储过程
--取当前数据库所有表的记录数
If exists (select top 1 name from sysobjects where id=object_id(N'[dbo].[GetAllTableRecordCount]') and
objectproperty(id,N'isprocedure')=1)
Drop procedure GetAllTableRecordCount
go
create procedure GetAllTableRecordCount
@oneTable nvarchar(50)=null
as
begin
--临时表
create table #temp
(
Table_Name nvarchar(50) null,
Table_Count int null
)
--查单表
if (@oneTable is not null)
begin
exec ('select ''' + @oneTable +''' as Table_Name, count(*) as Table_Count from ' + @oneTable)
return
end
Declare @table_name nvarchar(50)
--通过游标循环赋值给SQL变量
--定义游标
Declare cursor_name Cursor for
Select table_name from information_ where table_type='base table'
--打开游标
Open cursor_name
--打开游标后,指针指在第一条记录之前
--定位游标记录,并赋值入变量
Fetch next from cursor_name into @table_name
--开始循环操作
While @@fetch_status=0
Begin
exec ('insert into #temp (table_name,table_count) select ''' + @table_name + ''', COUNT(*) from ' + @table_name)
--定位下一条记录,并赋值
Fetch next from cursor_name into @table_name
End
--关闭游标
Close cursor_name
Deallocate cursor_name
select * from #temp
end
go
--示例
--exec GetAllTableRecordCount 'cust_xm_hxpp_ex_subject'
63. 部份其他资料
费用明细单(功能完善)(参考资料)
功能完善:根据单据类型的编号设定,控制单号的可用状态及显示。
传入:单据类型ID
返回:编号方式
需要引用:,以及(基类字段在此dll内)
(待写)
费用明细单单据类型(功能完善)
功能完善:生效日期默认为当前日期。
在UI代码>>Model>> AfterInitModel中增加:
ffective_tValue = ;
功能完善:控制编号方式为“手工编号”时,编号规则不可编辑。如图
方法一:启用TextChanged事件+部份代码控制(此方法较原始,呈现效果不太好,启用事件使用的是PostBack全局刷
新)
TextChanged事件代码:
private void DocHeaderSequenceStyle37_TextChanged_Extend(object sender, EventArgs e)
{
//0为自动编号
if (((ropDownListAdapter)sender).("0"))
{ ((IUIFieldBindingDataBindControl)derSequence25).ReadOnly = false; }
else
{
((IUIFieldBindingDataBindControl)derSequence25).ReadOnly = true;
derSequence = null;
derSequence_Code = ;
derSequence_Name = ;
}
DocHeaderSequenceStyle37_TextChanged_DefaultImpl(sender, e);
}
BeforeUIModelBinding中增加代码,(控制浏览时的显示)
// DocHeaderSequenceStyle==0,自动编号
if (dRecord != null)
{
if (derSequenceStyle == 0)
{ ((IUIFieldBindingDataBindControl)derSequence25).ReadOnly = false; }
else
{ ((IUIFieldBindingDataBindControl)derSequence25).ReadOnly = true; }
}
方法二:使用使能关联控件+部份代码控制(较优)
BeforeUIModelBinding中增加代码,(控制浏览时的显示)
// DocHeaderSequenceStyle==0,自动编号
if (dRecord != null)
{
if (derSequenceStyle == 0)
{ ((IUIFieldBindingDataBindControl)derSequence25).ReadOnly = false; }
else
{ ((IUIFieldBindingDataBindControl)derSequence25).ReadOnly = true; }
}
方法三:全代码控制(加CallBack代码)
(待验证)
功能完善二:没有勾选生效时,生效日期、失效日期只读,勾选了则为可编辑。如图
可用方法同上(功能完善一),这里使用方法三,全代码控制(加CallBack代码,这里控制enabled,暂未知如何控制
readonly)
AfterCreateChildControl中调用注册CallBack事件方法Register_CallBack_Effective_IsEffective_DoCustomerAction
private void Register_CallBack_Effective_IsEffective_DoCustomerAction()
{
//结合控件
ationControl ac = new AssociationControl();
//设定触发源
ServerControl = (CheckBox)ive_IsEffective34;
//设定事件名称,经验证区分大小写,可查看portaljs对应控件.js
ame = "onchange";
//查看事件的方法
//kBoxEventName
//客户端刷新框架
ClientCallBackFrm cF = new ClientCallBackFrm();
//加入相关控件(才可取其值)
((IUFControl)ive_IsEffective34);
(ac);
//加事件
omerAction +=
Customer(CallBack_Effective_IsEffective_DoCustomerAction);
}
private object CallBack_Effective_IsEffective_DoCustomerAction(CustomerActionEventArgs args)
{
//通过h,取得控件值,可通过监视sh察看所含值
//callbackform中,通过入的控件,才可用argshash得到其值
CheckBox f1 = (IUFFldCheckBox)ive_IsEffective34;
object value = sh[ID];
//用于设置控件值,建立适配器,才能改变它的值
lientDatePickerAdapter a1 =
lientDatePickerAdapter(ive_EffectiveDate34);
lientDatePickerAdapter a2 =
lientDatePickerAdapter(ive_DisableDate38);
if ((ng()))
{
d = True;
d = True;
}
else
{
d = False;
d = False;
}
//加入client端实例
(InstanceWithEnable);
(InstanceWithEnable);
return args;
}
BeforeUIModelBinding中增加代码,(控制浏览时的显示)
if (dRecord != null)
{
if (ean(ive_IsEffective))
{
ive_d = true;
ive_d = true;
}
else
{
new
new
new
ive_d = false;
ive_d = false;
}
}
版权声明:本文标题:用友U9全部 课程讲解资料V3.0 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1710174282a560881.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论