dev1
问题
1.model创建不了?
2.从开发界面双击进入后,如何返回?
3.一个客户端界面的所有东西就是一个项目吗?多个项目的数据全部储存在开发界面的aot中?
4.最终的测试是需要完成一个什么东西?
1.学习目标
2.dynamic ax
2.1介绍
2.2 ax功能
3.客户工作空间
文档主要介绍了三个界面
1.导航
2.内容:角色、列表、区域
3.客户列表页面
4.dynamic ax的体系结构
5.SQL server
操作部分
3.name 、Label和Help test
name :是后台开发人员对部件的命名
Label: 是显示在客户端的命名
Help text:是鼠标悬停时的解释说明文字
4.Table方法
4.1 DeleteAction
DeleteAction该方法为在删除表数据时,有关联表的情况下,如何删除
cascade:表示“在删除时,会把主表和从表的数据全部删除”
Restricted:表示“在删除时,不管点击主表还是从表都删除不了”
4.2 find(注意是静态方法)
定义find方法
static yprClothes find(yprVetClotheStyle _yprVetClotheStyle, //传入查询参数据
boolean _forUpdate = false) //当修改,删除的等操作时为true,默认查询时false
{
yprClothes yprClothes;//定义表缓存
if (_yprVetClotheStyle)//判断参数是否为空
{
if (_forUpdate)
{
yprClothes.selectForUpdate(_forUpdate);
}
select firstonly yprClothes //开始查询
where yprClothes.yprClotheStyle == _yprVetClotheStyle;
}
return yprClothes;
}
调用测试
static void Job23(Args _args)
{
yprClothes yprClothes;
//查询 ,只做查询的话,可以设置为false
//yprClothes = yprClothes::find("款式2",false);
//if (yprClothes)
// {
// info("查到的数据为: "+yprClothes.yprColorId);
// }
//增删改时要传入true
yprClothes = yprClothes::find("款式2",true);
if (yprClothes)
{
ttsBegin;//操作数据时,要加事务
//删除
//yprClothes.delete();
//更新
yprClothes.yprColorId="1";
yprClothes.update();
info("更新成功");
ttsCommit;
}
}
4.1 exist(注意是static方法)
定义exist方法
static boolean exist(yprVetClotheStyle _yprVetClotheStyle)//再传入参数的时候,是edt类型
{
return _yprVetClotheStyle && (select firstonly yprClotheStyle from yprClothes
where yprClothes.yprClotheStyle == _yprVetClotheStyle).yprClotheStyle != "";
}
调用测试
static void Job24(Args _args)
{
//boolean b;
yprClothes yprClothes;
boolean b = yprClothes::exist("款式2");
// info();
print(b);
pause;
}
5.Filed Group的使用
5.1 使用Filed Group的目的
当一个表单使用表格中的一部分数据的时候,可以通过创建字段组来引入
5.2 使用Filed Group的步骤
1.在table中建立好Filed Group
2.在form的design节点中创建一个Group,
3.在Group中的DataSource属性指定表
4.在Group中的DataGroup属性指定字段组
6.应用程序对象服务器
作用和具体干的事儿
7.Enum的创建
7.1 为什么使用enum
原因:当一个变量的取值为固定数据的的话可以考虑使用枚举
eg:性别,星期数。。。。
好处: 例如性别只有男女两种,如果不使用枚举的话,在传参之前需要保证参数的安全性(只能是“男”or“女”.不能是其他数据),而使用枚举则可以解决这样的问题。
7.2 创建enum的步骤
1.在AOT中找到Base Enum > new Base Enum
2.设置name属性
3.设置label属性,注意在设置label的时候需要注意:label其实就是一个解释说明的作用,此说法还有待考证。
4.设置UseEnumValue为Yes
8.Edt的创建
8.1Edt的创建的属性
label:
help text:
NoDecimal(针对Real类型数据):设置小数点
edt继承 transdate:设置提供图标
StringSize(针对String):字符大小
AllowNegative:是否允许为负数
8.2Edt的创建步骤
1.点击数据字典
2.new Extend type
3.改name
9.数据类型
9.1Date类型显示日期按钮
让日期edt继承transdate
10.表格
10.1 表格的属性列表
label:
help text:
mandatory:是否为空
allowEdit:是否允许被编辑
StringSize(针对String):字符大小
10.2 表格的建立
1.创建table、改名
2.将edt拖到field、改名
11.索引和主索引
10.1 创建索引的步骤
1.在table节点下的右击Indexs节点 new Index
2.改名index
3.将设置缩影的field拖到index节点
4.修改index中allowduplates设置为No(不允许重复)
10.2 主索引(主索引对应的field=主键)
1.将table中的PrimaryIndex属性设置为索引值
12.关系(两表关系,三表关系)
12.1关系的建立步骤(两表)
以从表为主,把从表设置好之后再去将edt拖到主表中
1.在Edt属性中设置RelationTable(表示该edt和那个表相关联)
2.展开Edt节点,创建一个>new> Table Renfernce
3.设置RelationFiled (设置相关字段,表示该edt和‘相关表’中的哪个字段关联,该字段为关联表中的filed)
4.把该Edt节点拖到另外一个表中的Filed节点,修改name和3步骤中的name同名
5.如果Edt被引用的表中的关联字段为主键,则会在另外一个表中的Relations中自动新建一组关系,表示“表之间的关联”,如果不是主键则需要自己new > Relations 设置关联字段
12.2多表关系
流程和两表差不多,大致步骤如下:
1.给表设置好主键
2.给“与表对应的Edt设置RelationTable”,同时在Edt节点new>Table References,添加相关表的Relation filed
3.把edt拖到目标表中改名。
13.表单
13.1 表单的构成元素
13.1 普通的表单建立
1.new from>property修改name为“SpeciesFrom”
2.添加数据源data resource(从table中拖过来)
3.在designs>design 中new controller>grid
4.将数据源中的属性拖到grid中
5.在desgin中修改属性caption(表单的主题名)
6.保存>ctrl+o
13.2 两个关系表单的建立
1.在13.1的基础上,把第二个表(BreedTable)托到SpeciesFrom”
2.在SpeciesFrom表单的数据源(BreedTable)属性中将joinSource设置为“SpeciesTable”
3.在SpeciesFrom表单的design节点中新建一个Gird
4.把数据源BreedTable中的字段filed拖到Gird中,并在Gird节点的属性中把DataSourse设置为“BreendTable‘(因为dynamics会默认设置为第一个数据源)
5.在SpeciesFrom表单的design节点属性中将Columns属性设置为2(表示一个表单中存放两个网格)
14.表单项
14.1表单项的创建
1.new Menu Item (display类型)
2.在新的表单项中的属性中将Object设置为“SpeciesFrom”
3.save>open
之后就会看到表单内容
14.2向区域页面添加表单项
1.在Menu中找到对应的节点,创建一个新的Submenu
2.将创建好的menu item 拖到Submenu中
3.save>open>即可看到
15.表单模板
15.1表单模板类型
15.2表单模板的使用
16.将菜单项添加到列表页面
这里是引用
17.练习题(2、3)建 关联form
17.1 参考示例
17.2 建立步骤
1.操作按钮的设置
1.在form的design中新建一个ActionPane>new ActionPaneTab>ButtonGroup>commandButton,
(注意1)在ActionPane属性中Style为Strip,按钮会横向排列,否则会竖向排列。
(注意2)在ButtonGroup中必须把属性datasource设置,不然操作不到数据。
2.commandButton的属性当中
ImageLocation(图标数据源):EmbeddedResource
NormalImage(图标代码):11024(add)10112(delete)
Text(按钮文字说明): eg:add/delete/update
ButtonDisplay(图标和文字的显示设置):Text & Image left
command(说明是add按钮还是delete按钮):eg:new 260
2.表格网格的设置
1.在desgin中>new Group>new Tab>new TabPage
在TabPage将属性caption设置
2.然后在TabPage中>new Grid
3.把字段从数据源中拖过来
(注意):如果有连个表的话,需要
(1)在form的datasource中把从表属性JoinSource改为第一个表
(2)在Grid中把从表的datasource改为从表本身(因为系统会默认把所有数据源设为第一个表)
17.3 相关属性的设置
17.4 如何在form的title中设置表字段(动态)
1.在form的design节点属性中指定titleDatasource
2.在指定的表属性中设置titleFiled1和titleFiled2
dev2
1.数据类型的分类
2.复合数据类型
3.复合数据类型的使用
4.方法
5.方法的使用
static void Job19(Args _args)
{
//info("Micorisoft Dynamic Ax is fantastic");
str s = "str";
int i = 33;
real double = 2.22;
container c = [s,i,double];
info(int2str(conLen(c)));
//print conLen(c);
//pause;
//info针对于Stringl类型
//conLen针对于复合类型container,同时在使用conLen的时候需要pause暂停一下
//
}
6.运算符
关系运算符
7.操作符的优先级
8.语句
8.1 条件语句
三种:
1.if
2.if else
3.switch
4.三元运算符
8.2 循环语句
1.while(){}
2.do while(){}
3.for()
str的方法
9.通信工具
在执行pause时会冻结运行的过程,如果此时用户点击继续则会执行结束,如果点击暂停则会终端,此时可以加入消息对话框
9.1消息框
警告对话框
选择消息框
9.2对话框
Dialog dialog;
DialogGroup dialogroup;
DialogField dialogfiled;
dialog = new Dialog("caption");
dialogroup=dialog.addGroup("title");
dialogfiled = Dialog.addField(extendedTypeStr(CustAccount));
if(dialog.run()){
print dialogfiled.value();
pause;
}
9.3 练习题
创建yesno框
创建InfoLog Tree
创建用户对话框,需要用户输入两个参数
创建一个用户yesno框,让用户选择是否输出出生日期
10.数据类型的转化
int2str
int类型转化为str类型
data2str
data类型转化为str类型
strFmt
:字符串的输出格式strFmt(%1,%2,str1,str2)
******相关方法总结
1.mkDate:定义日期
2.date2str:
应用:
11.类
11.1 类的组成和类的创建(方法的创建)
这里是引用
11.2 类的访问修饰符
11.3 类的继承的特征
11.3 类的实例化
1.父类
>
2.子类
3.实例化子类,调用父类方法
11.4 方法的定义和方法的返回值
11.5 在同一个类中方法可以互相调用(this)
使用 this
11.6 方法的分类
11.6.1 静态方法的调用
11.6.2 display方法
一个表可以作为一个类,用来显示表单上的值
11.6.3 accessor方法
通过设置默认值的方式,如果有传参则使用传参,如没有传参则使用默认值
11.6.4 table as classes
12.事件
12.1添加Post事件
不理解
13 .计算器
14.练习题(4)求税
14.1 业务逻辑
略
14.2 相关代码
14.3 Map的使用
14.3.1 Map创建和插入值
public static Map getMap()//获取数据
{
Map map;
map = new Map(types::String,types::real);
map.insert("Beijing",0.14);
map.insert("Shanghai",0.12);
map.insert("Tianjin",0.1);
map.insert("Chongqing",0.08);
map.insert("Others",0.8);
return map;
}
14.3.2 Map通过key值获取
public static real getWithholdingTaxRate(str city)//根据具体的city获取rate
{
Map map;
real cityRate;
map = yprClidrenTax::getMap();//获取map数据
if (map.exists(city))
{
cityRate = map.lookup(city);//根据city获取rate
}
else
{
cityRate = 0.08;
}
return cityRate;
}
14.3.3 Map遍历和取值
public void showAllCityTax(int amount)
{
Map map;
MapEnumerator mapEnumerator;//定义迭代器
real cityRate;
real tax;
map = yprClidrenTax::getMap();//获取map数据
mapEnumerator=map.getEnumerator();//创建迭代器
while(mapEnumerator.moveNext())
{ //通过迭代器获取key和value
cityRate=yprClidrenTax::getWithholdingTaxRate(mapEnumerator.currentKey());
tax=cityRate*amount;
//print tax;
info(strFmt("%1:<%2>", mapEnumerator.currentKey(),tax));
}
}
14.4 注意事项
14.4.1 使用accessor方式给全局变量赋值
public real parmTaxRate(real _taxRate =taxRate)
{ //taxRate为税率
taxRate=_taxRate;
return taxRate;
}
14.4.2 子类继承父类的时候,重写父类方法
步骤:
在aot中>右键子类>overied method>点击方法 即可创建
14.4.3 使strFmt打印
info(strFmt("%1:<%2>", mapEnumerator.currentKey(),tax));
访问数据库
12.操作语句(实践)
12.1insert
yprColor yprColor;
yprColor.yprColorId="4";
yprColor.yprDescription="灰色";
yprColor.insert();
12.2查询全表字段
select yprColor
where yprColor.yprColorId=="4";
info(yprColor.yprDescription);
12.3查询部分字段
select yprDescription from yprColor
where yprColor.yprColorId=="4";
12.4 查询多行数据(范围查询)(注意格式写法)
格式:在末尾需加上{ },中括号中语句后加分号;
while select yprClothes
where yprClothes.yprColorId > "0" && yprClothes.yprColorId < "3"
{
info(strFmt("%1",yprClothes.yprPrice));
}
12.5 排序
12.5.1 按照索引排序
yprColor yprColor;
while select yprColor index yprColorIdx //按照yprColorId排序
{
info(yprColor.yprDescription); //输出颜色
}
12.5.2 按照order by排序
//按照order by
yprColor yprColor;
while select yprColor order by yprColorId asc
{
info(yprColor.yprDescription);
}
12.5.3 按照Group by排序求数量
//按照group by
yprColor yprColor;
while select count(RecId) from yprColor group by yprColor.yprDescription
{
info(yprColor.RecId);
}
12.5.3 按照Group by排序求平均值
//按照部门分组,求各部门员工的平均年龄
yprEmployeeTable yprEmployeeTable;
while select avg(Age) from yprEmployeeTable
group by yprEmployeeTable.DepartId
{
info(strFmt("id:%1 的平均年龄为:%2",yprEmployeeTable.DepartId,yprEmployeeTable.Age));
}
12.6 多表联查
//多表联查,加条件,查出每个员工所属的部门名
yprEmployeeTable yprEmployeeTable;
yprDepartmentTable yprDepartmentTable;
while select yprEmployeeTable
join yprDepartmentTable
where (yprEmployeeTable.DepartId==yprDepartmentTable.DepartmentId)
{
info(strFmt("员工:%1 的部门名为:%2",yprEmployeeTable.Name,yprDepartmentTable.Name));
}
12.7 联查+更新(如何赋值enum值格式待补充)
注意: 更新哪个表,该表必须跟在forupdate后
如何赋值enum值格式待补充?
//多表联查+更新 eg:考核题中的需求(业绩表)
yprEmployeeTable yprEmployeeTable;
yprPerformanceTable yprPerformanceTable;
ttsBegin;
while select forUpdate yprPerformanceTable
join yprEmployeeTable
where (yprEmployeeTable.EmployeeId==yprPerformanceTable.EmployeeId)
//&& yprPerformanceTable.PerformanceType=="Attendance"
&& yprPerformanceTable.Grade<0.6
{
yprPerformanceTable.Grade=0.6;
yprPerformanceTable.update();
info(strFmt("员工:%1 修改为:0.6",yprEmployeeTable.Name));
}
ttsCommit;
12.8 条件(日期格式)查询
//条件查询(日期格式)如何比较日期
while select yprEmployeeTable
where yprEmployeeTable.EntryDate<mkDate(20,11,22)//使用mkDate(日,月,年(后两位))表示
{
info(strFmt("员工为:%1",yprEmployeeTable.Name));
}
12.9 使用Query分组查询+统计数量:参考文章
//使用query进行分组查询 + 统计数量
Query query;
QueryBuildDataSource qbds;
QueryBuildFieldList qbfl;
QueryRun qr;
query = new Query();
qbds = query.addDataSource(TableNum(yprEmployeeTable));//连接数据源
qbds.addGroupByField(fieldnum(yprEmployeeTable,DepartId));//添加要分组的字段
qbfl = qbds.fields();//向QueryBuildFieldList中添加表中的字段值
qbfl.addField(fieldnum(yprEmployeeTable,Name),SelectionField::Count);
//通过添加QueryBuildFieldList,添加分组后统计的类型为Count
qr = new QueryRun(query);
while(qr.next())
{
yprEmployeeTable = qr.get(TableNum(yprEmployeeTable));//获取查询后的值
info(strFmt("部门:%1的数量为:%2",yprEmployeeTable.DepartId,yprEmployeeTable.Name)); //取值
}
12.10 分组后统计组中的最大、最小值
分组后求最大值和最小值需要先分组,把分完组的数据放到view中,再从view中通过maxof等方法求值
12.10.1 步骤1 在Aot中建query
见本笔记 12.11.3章节
12.10.2 步骤2 在Aot中建View
1.new > view
2.展开创建好的view节点属性表,设置name和query源
3.展开query节点,右键Filed节点new field
4,在设置特殊的Count、Sum、Avg等特殊字段时,需要在字段属性表中,选取在query中建立的特殊字段
5.同步数据库:右击view>compile>synchronize
12.10.3 步骤3 在Job中查询view
yprView yprView;//定义view
select maxof(yprCount) from yprView;//在view中查询
info(strFmt("最大值为:%1",yprView.yprCount));输出值
12.11 三种查询数据的方式
12.11.1 第1种 sql查询
yprEmployeeTable yprEmployeeTable;
while select count(RecId) from yprEmployeeTable
group by yprEmployeeTable.DepartId
{
info(strFmt("部门 : %1 数量为:%2",yprEmployeeTable.DepartId,yprEmployeeTable.RecId));
}
12.11.2 第2种 使用Query代码
Query query;//求分组后的数量
QueryBuildDataSource qbds;
QueryBuildFieldList qbfl;
QueryRun qr;
yprEmployeeTable yprEmployeeTable;
query = new Query();
qbds = query.addDataSource(tableNum(yprEmployeeTable));
qbds.addGroupByField(fieldnum(yprEmployeeTable,DepartId));//添加要分组的字段
qbfl = qbds.fields();
qbfl.addField(fieldnum(yprEmployeeTable,RecId),SelectionField::Count);
qr = new QueryRun(query);
while(qr.next())
{
yprEmployeeTable = qr.get(tableNum(yprEmployeeTable));
info(strFmt("部门:%1 的数量为:%2",yprEmployeeTable.DepartId,yprEmployeeTable.RecId));
}
12.11.3 第3种 使用AOT创建Query
(1)在AOT中创建Query
1.new>Query
2.把表数据拖到Query中的Data Sourse
3.展开数据源节点>在展开表节点
4.右键 Group by 节点添加“分组字段”
5.在Filed节点中添加分组后要展示的字段
6.保存
(2)在Job中结合query语句查询
Query query;
QueryRun qr;
yprEmployeeTable yprEmployeeTable;
query = new Query(queryStr(yprQuery5));
qr = new QueryRun(query);
while(qr.next())
{
yprEmployeeTable = qr.get(tableNum(yprEmployeeTable));
info(strFmt("部门:%1 的数量为:%2",yprEmployeeTable.DepartId,yprEmployeeTable.RecId));
}
13.三个重要的方法
13.1 lookup()
此方法适用于两个字段以上,如果是两个字段的话在表中直接设置titleField1和titleField2
需求用途:
创建lookup步骤:
1.展开 form节点>design>…Gird>具体得字段
2.右击 该属性得method> override method> lookup
3.根据需求创建以下代码:参考文章
public void lookup()
{
Query query;
QueryBuildDataSource queryBuildDataSource;
SysTableLookup lookup;
yprEmployeeTable yprEmployeeTable;
//初始化Query
query = new Query();
//调用SysTableLookup的静态方法
lookup = SysTableLookup::newParameters(tableNum(yprEmployeeTable), this);
//引入数据源
queryBuildDataSource = query.addDataSource(tableNum(yprEmployeeTable));
//添加需要展示的字段
lookup.addLookupfield(fieldNum(yprEmployeeTable, EmployeeId));
lookup.addLookupfield(fieldNum(yprEmployeeTable, Name), true); //returns the Invoicing Name
lookup.addLookupfield(fieldNum(yprEmployeeTable, EntryDate), true);
//通过以下方式添加排序,让下拉时展示数据按照某种顺序
//queryBuildDataSource.addOrderByField(fieldnum(InventSite, Name));
//添加query
lookup.parmQuery(query);
lookup.performFormLookup();
}
13.2 display
**需求用途:**当把小数用百分号表示时,如果属性中没有可设置的途径,可通过display方法进行自定义,在自定义时需要先“添加一个扩展数据类型”,将该类型的数据在方法中展示。
步骤1:
1.创建edt类型数据
2.记得保存(如果不保存,后面在form中打开后不显示字段名)
步骤2:
1.在table中的method节点中>new method
2.输入以下代码
//display修饰,表示该方法再form中打开时被调用
//yprGradeTest2为创建的edt
display yprGradeTest2 displayGrade()
{
return strFmt("%1%", this.Grade * 100);
//自定义返回的格式
}
步骤3:
将原本的数据字段设置“不显示”,在form表单中过的Grid中设置
3.save
13.3 modifiedFiled
需求用途:如下图:因为员工表和部门表时具有相关性的,所以当我们在点击某个员工时,此时应该自动显示该员工对应的部门信息
实现:通过给table添加modifiedField方法,该方法为一旦用户点击了下拉列表中的某个值时,此时触发modifiedField方法:根据选中的值会去查找对应的部门信息,然后返回,最后动态的显示在表单上。
步骤:
1.展开table节点>methode>new method
2.命名为:modifiedField
3.添加以下代码完成实现
public void modifiedField(FieldId _fieldId)//_fieldId为在下拉列表中的选中的值
{
yprEmployeeTable yprEmployeeTable;//定义表格
super(_fieldId);
switch (_fieldId)//通过Switch的方式匹配选中的值
{
case fieldNum(yprPerformanceTable, EmployeeId):
yprEmployeeTable = yprEmployeeTable::find(this.EmployeeId);
this.DepartmentId = yprEmployeeTable.DepartId;
break;
}
}
数据库操作
15.9 insert
15.9.1 insert(单行数据)
15.9.2 insert(通过复制插入多行数据)
15.10 update
15.10.1 update(单行数据)
更新时需要注意的问题