S/4 HANA中的ACDOCT和FAGLFLEXT
最近的几个需求让我对ACDOCT和FAGLFLEXT这两个财务相关表(准确地说是视图)产生了一些了解,同时也发现某些开发同行和业务顾问并没有认识到这些东西。因此我打算从技术角度来说明一下这两个视图在S4中的实际面貌。当然因为我并不了解FICO方面的任何业务知识,所以也只是进行技术角度的说明。
本文内容基于 S/4 1709版本;某些内容可能和其他版本不是完全符合,特别是具体的DDL代码部分。
本文链接:http://www.cnblogs.com/hhelibeb/p/8629942.html
财务报表开发中经常会出现有关期初余额和本期发生额的需求,传统上获取期初余额的方式是从FAGLFLEXT或ACDOCT中获取结转余额(HSLVT),再加上各期发生额(HSL01, HSL02....)。
比如要获取公司1000的2018年3月的期初余额,ABAP代码的写法是:
SELECT SUM( ( hslvt + hsl01 + hsl02 ) ) FROM faglflext WHERE rbukrs = ''
AND ryear = ''
INTO @DATA(l_balance).
这只是段简单的示例代码,实际需求中可能要按科目等条件取出各个期间分组汇总。并且,为了适应动态的查询条件,通常要使用Field Symbol,在内表中对数据进行累加操作,颇为繁琐。
那么,HSLVT和HSL01, HSL02....等数据是从哪里来的呢?如果把FAGLFLEXT和ACDOCT视为数据库表,读者可能会认为,它们是通过某些结转操作,由系统汇总计算后得来并存储到数据库中的。但实际上,FAGLFLEXT和ACDOCT都只是视图,而非透明表。可以理解成,它们当中的数据不是数据库中既有的,而是和各种报表程序一样、是对其它表的数据进行实时处理后临时生成的结果。
打开SE11可以看到:


可以看到,它们实际上是ABAP CDS视图。如果不了解ABAP CDS视图的话,可以暂时把它理解成使用SQL语言建立的数据模型,通过使用注解,还能为它赋予其它能力。
推荐通过Eclipse来查看CDS视图的定义,具体操作方式不提。
CDS视图中的数据通常是从透明表中取得的,这里以FAGLFLEXT为例:
观察视图的DDL源,寻找其中的FROM关键字:
@AbapCatalog.sqlViewName: 'FAGLFLEXT'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@ObjectModel.usageType.serviceQuality: #X
@ObjectModel.usageType.sizeCategory: #XL
@ObjectModel.usageType.dataClass: #MIXED
@EndUserText.label: 'FAGLFLEXT (Compatibility View) '
@AbapCatalog.preserveKey: true define view v_faglflext_view
as
select key rclnt, key ryear,
key objnr00, key objnr01, key objnr02, key objnr03, key objnr04, key objnr05, key objnr06, key objnr07, key objnr08,
key drcrk, key rpmax,
activ, rmvct, rtcur, runit, awtyp,
rldnr, rrcty, rvers, logsys, racct, cost_elem, rbukrs,
rcntr, prctr, rfarea, rbusa, kokrs, segment, zzpaytype, zzinvunit, zzempnum, ps_posid, aufnr, kunnr, lifnr,
//<$VF>
//<$FIELDS>
//<$VF>
scntr, pprctr, sfarea, sbusa, rassc, psegment,
tslvt, tsl01, tsl02, tsl03, tsl04, tsl05, tsl06, tsl07, tsl08, tsl09, tsl10, tsl11, tsl12, tsl13, tsl14, tsl15, tsl16,
hslvt, hsl01, hsl02, hsl03, hsl04, hsl05, hsl06, hsl07, hsl08, hsl09, hsl10, hsl11, hsl12, hsl13, hsl14, hsl15, hsl16,
kslvt, ksl01, ksl02, ksl03, ksl04, ksl05, ksl06, ksl07, ksl08, ksl09, ksl10, ksl11, ksl12, ksl13, ksl14, ksl15, ksl16,
oslvt, osl01, osl02, osl03, osl04, osl05, osl06, osl07, osl08, osl09, osl10, osl11, osl12, osl13, osl14, osl15, osl16,
mslvt, msl01, msl02, msl03, msl04, msl05, msl06, msl07, msl08, msl09, msl10, msl11, msl12, msl13, msl14, msl15, msl16,
timestamp
from faglflext_bck where rrcty = ''
union all
select
key rclnt,
key cast(ryear as gjahr) as ryear,
key cast(objnr00 as g_objnr) as objnr00,
key cast(objnr01 as g_objnr) as objnr01,
key cast(objnr02 as g_objnr) as objnr02,
key cast(objnr03 as g_objnr) as objnr03,
key cast(objnr04 as g_objnr) as objnr04,
key cast(objnr05 as g_objnr) as objnr05,
key cast(objnr06 as g_objnr) as objnr06,
key cast(objnr07 as g_objnr) as objnr07,
key cast(objnr08 as g_objnr) as objnr08,
key cast(drcrk as shkzg) as drcrk,
key cast(rpmax as rpmax) as rpmax,
cast(activ as acti1) as activ,
cast(rmvct as rmvct) as rmvct,
cast(rtcur as rtcur) as rtcur,
runit,
cast(awtyp as awtyp) as awtyp,
cast(rldnr as fagl_rldnr) as rldnr,
cast(rrcty as rrcty) as rrcty,
cast(rvers as rvers) as rvers,
cast(logsys as logsys) as logsys,
cast(racct as racct) as racct,
cast(cost_elem as kstar) as cost_elem,
cast(rbukrs as bukrs) as rbukrs,
cast(rcntr as kostl) as rcntr,
cast(prctr as prctr) as prctr,
cast(rfarea as fkber) as rfarea,
cast(rbusa as gsber) as rbusa,
cast(kokrs as kokrs) as kokrs,
cast(segment as fb_segment) as segment,//<$VF>
//<$FIELDS>
//<$VF>
cast(scntr as skost) as scntr,
cast(pprctr as pprctr) as pprctr,
cast(sfarea as sfkber) as sfarea,
cast(sbusa as pargb) as sbusa,
cast(rassc as rassc) as rassc,
cast(psegment as fb_psegment) as psegment,
cast(tslvt as tslvt12) as tslvt,
cast(tsl01 as tslxx12) as tsl01,
cast(tsl02 as tslxx12) as tsl02,
cast(tsl03 as tslxx12) as tsl03,
cast(tsl04 as tslxx12) as tsl04,
cast(tsl05 as tslxx12) as tsl05,
cast(tsl06 as tslxx12) as tsl06,
cast(tsl07 as tslxx12) as tsl07,
cast(tsl08 as tslxx12) as tsl08,
cast(tsl09 as tslxx12) as tsl09,
cast(tsl10 as tslxx12) as tsl10,
cast(tsl11 as tslxx12) as tsl11,
cast(tsl12 as tslxx12) as tsl12,
cast(tsl13 as tslxx12) as tsl13,
cast(tsl14 as tslxx12) as tsl14,
cast(tsl15 as tslxx12) as tsl15,
cast(tsl16 as tslxx12) as tsl16,
cast(hslvt as hslvt12) as hslvt,
cast(hsl01 as hslxx12) as hsl01,
cast(hsl02 as hslxx12) as hsl02,
cast(hsl03 as hslxx12) as hsl03,
cast(hsl04 as hslxx12) as hsl04,
cast(hsl05 as hslxx12) as hsl05,
cast(hsl06 as hslxx12) as hsl06,
cast(hsl07 as hslxx12) as hsl07,
cast(hsl08 as hslxx12) as hsl08,
cast(hsl09 as hslxx12) as hsl09,
cast(hsl10 as hslxx12) as hsl10,
cast(hsl11 as hslxx12) as hsl11,
cast(hsl12 as hslxx12) as hsl12,
cast(hsl13 as hslxx12) as hsl13,
cast(hsl14 as hslxx12) as hsl14,
cast(hsl15 as hslxx12) as hsl15,
cast(hsl16 as hslxx12) as hsl16,
cast(kslvt as kslvt12) as kslvt,
cast(ksl01 as kslxx12) as ksl01,
cast(ksl02 as kslxx12) as ksl02,
cast(ksl03 as kslxx12) as ksl03,
cast(ksl04 as kslxx12) as ksl04,
cast(ksl05 as kslxx12) as ksl05,
cast(ksl06 as kslxx12) as ksl06,
cast(ksl07 as kslxx12) as ksl07,
cast(ksl08 as kslxx12) as ksl08,
cast(ksl09 as kslxx12) as ksl09,
cast(ksl10 as kslxx12) as ksl10,
cast(ksl11 as kslxx12) as ksl11,
cast(ksl12 as kslxx12) as ksl12,
cast(ksl13 as kslxx12) as ksl13,
cast(ksl14 as kslxx12) as ksl14,
cast(ksl15 as kslxx12) as ksl15,
cast(ksl16 as kslxx12) as ksl16,
cast(oslvt as oslvt12) as oslvt,
cast(osl01 as oslxx12) as osl01,
cast(osl02 as oslxx12) as osl02,
cast(osl03 as oslxx12) as osl03,
cast(osl04 as oslxx12) as osl04,
cast(osl05 as oslxx12) as osl05,
cast(osl06 as oslxx12) as osl06,
cast(osl07 as oslxx12) as osl07,
cast(osl08 as oslxx12) as osl08,
cast(osl09 as oslxx12) as osl09,
cast(osl10 as oslxx12) as osl10,
cast(osl11 as oslxx12) as osl11,
cast(osl12 as oslxx12) as osl12,
cast(osl13 as oslxx12) as osl13,
cast(osl14 as oslxx12) as osl14,
cast(osl15 as oslxx12) as osl15,
cast(osl16 as oslxx12) as osl16,
cast(mslvt as mslvt12) as mslvt,
cast(msl01 as mslxx12) as msl01,
cast(msl02 as mslxx12) as msl02,
cast(msl03 as mslxx12) as msl03,
cast(msl04 as mslxx12) as msl04,
cast(msl05 as mslxx12) as msl05,
cast(msl06 as mslxx12) as msl06,
cast(msl07 as mslxx12) as msl07,
cast(msl08 as mslxx12) as msl08,
cast(msl09 as mslxx12) as msl09,
cast(msl10 as mslxx12) as msl10,
cast(msl11 as mslxx12) as msl11,
cast(msl12 as mslxx12) as msl12,
cast(msl13 as mslxx12) as msl13,
cast(msl14 as mslxx12) as msl14,
cast(msl15 as mslxx12) as msl15,
cast(msl16 as mslxx12) as msl16,
cast(timestamp as timestamp) as timestamp
from FGL_FAGLFLEXT
可以发现这个视图结合了2个源。其一是FAGLFLEXT_BCK,查询可知这是旧数据的备份表;另一个是FGL_FAGLFLEXT,
打开FGL_FAGLFLEXT,发现它还是个CDS视图(因为完整定义过长,只截取了部分代码,下同):
@AbapCatalog.sqlViewName: 'FGLV_FAGLFLEXT'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@ObjectModel.usageType.serviceQuality: #X
@ObjectModel.usageType.sizeCategory: #XL
@ObjectModel.usageType.dataClass: #MIXED
@EndUserText.label: 'Compatibility view for FAGLFLEXT'
define view FGL_FAGLFLEXT as select from FGL_GLTT2
{
key rclnt,
key ryear,
key cast(objnr00 as abap.int4(10)) as objnr00,
key cast(objnr01 as abap.int4(10)) as objnr01,
key cast(objnr02 as abap.int4(10)) as objnr02,
key cast(objnr03 as abap.int4(10)) as objnr03,
key cast(objnr04 as abap.int4(10)) as objnr04,
key cast(objnr05 as abap.int4(10)) as objnr05,
key cast(objnr06 as abap.int4(10)) as objnr06,
key cast(objnr07 as abap.int4(10)) as objnr07,
key cast(objnr08 as abap.int4(10)) as objnr08,
key drcrk,
key rpmax,
activ,
………………
………………
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hslvt) as hslvt,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl01) as hsl01,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl02) as hsl02,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl03) as hsl03,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl04) as hsl04,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl05) as hsl05,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl06) as hsl06,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl07) as hsl07,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl08) as hsl08,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl09) as hsl09,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl10) as hsl10,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl11) as hsl11,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl12) as hsl12,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl13) as hsl13,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl14) as hsl14,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl15) as hsl15,
@Semantics.amount.currencyCode: 'T882G.CURR1' sum(hsl16) as hsl16,
………………
………………
max(timestamp) as timestamp
}
group by
………………
………………
可以看到,FGL_FAGLFLEXT中的HSLVT和HSL01, HSL02字段,是对FGL_GLTT2中相应字段的汇总得来的。对应语句:sum(hslvt) as hslvt。
打开FGL_GLTT2,会发现该视图中的金额汇总自FGL_GLTT1,所以这里就不贴FGL_GLTT2的定义了,直接看FGL_GLTT1:
@AbapCatalog.sqlViewName: 'FGLV_GLTT1'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@ObjectModel.usageType.serviceQuality: #X
@ObjectModel.usageType.sizeCategory: #XL
@ObjectModel.usageType.dataClass: #MIXED
@EndUserText.label: 'G/L totals: create the period block'
define view FGL_GLTT1 as select from FGL_GLTT0
{
rclnt,
ryear,
0 as objnr00,
0 as objnr01,
0 as objnr02,
0 as objnr03,
0 as objnr04,
0 as objnr05,
0 as objnr06,
0 as objnr07,
0 as objnr08,
drcrk, case poper
when '' then ''
else cast( lpad( cast ( 16 * (1 + div( cast(poper as abap.int4) - 1, 16) ) as abap.char(12) ), 3, '') as abap.numc(3))
end as rpmax,
activ, rmvct, rtcur,
runit, awtyp, rldnr, rrcty, rvers, logsys, racct, cost_elem, rbukrs,
rcntr, prctr, rfarea, rbusa, kokrs, segment,
scntr, pprctr, sfarea, sbusa, rassc, psegment,
//<$VF>
fikrs, rfund, rgrant_nbr, rbudget_pd, sfund, sgrant_nbr, sbudget_pd,
re_bukrs, re_account, vname, egrup, recid,
//<$FIELDS>
//<$VF>
………………
………………
case poper when '' then hsl else 0 end as hslvt,
case mod( cast(poper as abap.int4 ), 16) when 1 then hsl else 0 end as hsl01,
case mod( cast(poper as abap.int4 ), 16) when 2 then hsl else 0 end as hsl02,
case mod( cast(poper as abap.int4 ), 16) when 3 then hsl else 0 end as hsl03,
case mod( cast(poper as abap.int4 ), 16) when 4 then hsl else 0 end as hsl04,
case mod( cast(poper as abap.int4 ), 16) when 5 then hsl else 0 end as hsl05,
case mod( cast(poper as abap.int4 ), 16) when 6 then hsl else 0 end as hsl06,
case mod( cast(poper as abap.int4 ), 16) when 7 then hsl else 0 end as hsl07,
case mod( cast(poper as abap.int4 ), 16) when 8 then hsl else 0 end as hsl08,
case mod( cast(poper as abap.int4 ), 16) when 9 then hsl else 0 end as hsl09,
case mod( cast(poper as abap.int4 ), 16) when 10 then hsl else 0 end as hsl10,
case mod( cast(poper as abap.int4 ), 16) when 11 then hsl else 0 end as hsl11,
case mod( cast(poper as abap.int4 ), 16) when 12 then hsl else 0 end as hsl12,
case mod( cast(poper as abap.int4 ), 16) when 13 then hsl else 0 end as hsl13,
case mod( cast(poper as abap.int4 ), 16) when 14 then hsl else 0 end as hsl14,
case mod( cast(poper as abap.int4 ), 16) when 15 then hsl else 0 end as hsl15,
case mod( cast(poper as abap.int4 ), 16)
when 0 then
case poper
when '' then 0
else hsl
end
else 0 end
as hsl16,
………………
……………… timestamp
}
可以清楚地看到,原来结转余额HSLVT其实就是期间POPER = 000时的金额,HSL01,HSL02就是期间POPER = 001,002时的金额....
对应语句是:case poper when '000' then hsl else 0 end as hslvt,,和case mod( cast(poper as abap.int4 ), 16) when 1 then hsl else 0 end as hsl01
继续找下去可以得知FGL_GLTT1的数据来自于表ACDOCA(Universal Journal Entry Line Items)。也就是说,每次从FAGLFLEXT中查询数据,实际上相当于经过了FGL_GLSI_ACD->FGL_GLSI_ACD->FGL_GLTT1->FGL_GLTT2->FGL_FAGLFLEXT->V_FAGLFLEXT_DDL一系列中间层逻辑处理,其实际的数据源则是表ACDOCA。当然这些视图中可能还包含其它细节..
以上是对FAGLFLEXT的分析,ACDOCT也是差不多的,具体的条件有点差别。
FAGLFLEXT和ACDOCT的存在体现了CDS所具备的强大能力。不过,毕竟它们只是兼容视图,又包含这样多的中间层...按照一般的原则,程序中的中间层越多,性能就越差。因此,在了解到它们中的数据的实际来源后,也许在某些情况下,直接从ACDOCA中通过聚合函数获取期初余额之类的东西会有更好的性能。
按这样的思路改写文初获取1000公司在2018年3月的期初余额的代码,可以写成:
SELECT SUM( hsl ) FROM acdoca WHERE rbukrs = ''
AND gjahr = ''
AND poper < ''
INTO @DATA(l_balance).
是不是简单了很多呢?
最后,再次重申,本文只是从技术角度介绍下我对ACDOCT,FAGLFLEXT的了解。在实际业务中,这两个视图中的数据可能和分类账、凭证状态之类的东西有关...其中的数据与ACDOCA中的汇总数据并不一定在任何情况下都完全相等。
示例代码:
从ACDOCA中获取公司代码1000,分类账0L,科目1122020000的期初余额、本期发生额、期末余额、本年累计发生额:
REPORT ztest_balance. DATA: p_gjahr TYPE acdoca-gjahr VALUE '',
p_poper TYPE acdoca-poper VALUE ''. DATA: c_racct TYPE racct VALUE ''. WITH +itab AS (
SELECT
CASE WHEN poper < @p_poper AND gjahr = @p_gjahr THEN hsl
ELSE
END AS opening_balance,
CASE WHEN poper = @p_poper AND gjahr = @p_gjahr THEN hsl
ELSE
END AS current_balance,
CASE WHEN poper <= @p_poper AND gjahr = @p_gjahr THEN hsl
ELSE
END AS ending_balance,
CASE WHEN poper > '' AND poper <= '' AND gjahr = @p_gjahr THEN hsl
ELSE
END AS current_year_balance,
racct
FROM acdoca
WHERE racct = @c_racct
AND gjahr = @p_gjahr
AND rbukrs = ''
AND rldnr = '0L' )
SELECT
racct,
SUM( opening_balance ) AS opening_balance,
SUM( current_balance ) AS current_balance,
SUM( ending_balance ) AS ending_balance,
SUM( current_year_balance ) AS current_year_balance
FROM +itab
GROUP BY racct
INTO TABLE @DATA(lt_balance).
S/4 HANA中的ACDOCT和FAGLFLEXT的更多相关文章
- S/4 HANA中的MATDOC和MATDOC_EXTRACT
最近做了销售和物料管理方面的一些需求,因此对S/4中的MM的数据模型有了一定的了解.目前网络已经有一些介绍物料凭证表MATDOC的文章,内容好像不是很详细,另外也没发现介绍库存变更数据表MATDOC_ ...
- SAP HANA 中的决策表(Decision Table)
http://scn.sap.com/community/developer-center/hana/blog/2013/01/11/what-can-you-do-with-decision-tab ...
- SAP HANA中创建计算视图(Calculation View)
[Step By Step]SAP HANA中创建计算视图(Calculation View) Demo Instruction: 该视图将两个表AUDIOBOOKS和BOOKS中的数据进行连接,并作 ...
- SAP HANA中的SLT简介
在以SAP系统作为主要ERP的企业中,不同系统之间的数据库数据同步是个重要的工作.对于这种需求,除了开发ABAP接口之外,也有高效的工具可用.SLT就是其中之一. SLT是SAP的第一个ETL(Ext ...
- S/4 HANA中发票输出切换回NAST
在S/4 HANA中,新的输出管理Output Management叫做SAP S/4HANA output control(输出控制),是基于BRF+的,而不是原来基于NAST的.关于S4新的输出控 ...
- 【HANA系列】SAP HANA中null变成问号的问题
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA中null变成问 ...
- 【HANA系列】SAP UI5上传图片 用XSJS存储在HANA中的方法
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP UI5上传图片 用XSJ ...
- S/4 HANA中的数据库锁策略
S4中的新的MM数据模型以及HANA的Insert-only特性允许物料凭证的并行处理,提高了相关的吞吐量.由此,数据库锁的应用情况也发生了变化.下文将介绍这些变化(基于S4 1610). 本文链接: ...
- SAP HANA中创建层次分析视图(Hierarchy Analytic View)
1. 创建层次Attribute View: ATTR_PRODUCT_HIERACHY ref: http://www.cnblogs.com/omygod/archive/2013/04/30/ ...
随机推荐
- 压缩tar命令
option z表示压缩,所以才有后面的.gz, c表示创建这个压缩包,v是可视,能看到其打包和压缩的过程,f表示文件 zcvf 命令格式为 先压缩后跟压缩的目录 tar zcvf /home/xia ...
- 嵌入式Linux引导过程之1.4——Xloader的ddr_init
这里我们来看XLOADER_ENTRY中调用的第二个标号ddr_init处的代码,这部分代码的作用是对外部内存SDRAM进行初始化,在我 spearplus开发板中,使用的是DDR SDRAM.在调用 ...
- 小说接入UC浏览器内核技术对话(二)
质辛@灿岩 质辛跟我们说一下那个删除文件的逻辑吧质辛@灿岩 应该不是删除cache下所有文件吧?质辛质辛@智鹰 提供一下我们的临时文件完整路径给 灿岩吧质辛@智鹰 是负责我们ucsdk的 技术对 ...
- mysql事务介绍
什么是事务 一组sql语句操作单元组内所有sql完成一个业务如果整组成功,意味着组内的全部的sql成功如果其中任何一个失败,意味着整个操作失败 数据回到操作前的状态 事务的特点 1.多条sql语句组成 ...
- 基于am3358的led跑马灯测试
#include <sys/ioctl.h> #include<stdio.h> #include <fcntl.h> #include <sys/types ...
- freemarker报错之十二
1.错误描述 六月 04, 2014 10:31:47 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Template proc ...
- MyEclipse完善提示配置
MyEclipse完善提示配置 一般的,MyEclipse中的提示以"."后进行提示,不是很完善.现在,修改提示配置,让提示更完善! 具体操作如下: 1.打开MyEclipse,单 ...
- Linux显示工作路径
Linux显示工作路径 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ pwd /home/youhaidong
- Linux显示2015年日历表
Linux显示2015年日历表 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ cal 2015 2015 一月 二月 三月 日 一 二 三 四 五 六 日 一 ...
- Android APP开发入门教程-Button
代码编写 做好准备工作后,终于可以开始写我们的hello android了,在开始编写代码之前,我们先了解几个文件: res/layout/main.xml App主窗体布局文件,你的应用长什么样都在 ...