隐藏

Power Apps 中ForAll函数

发布:2024/10/11 15:40:32作者:管理员 来源:本站 浏览次数:27

ForAll函数的使用(嵌套循环&变量定义&逻辑判断&示例)


   奇思妙想:ForAll嵌套循环生成九九乘法表

       ForAll的语法规则

       ForAll循环固定次数 (Sequence函数)

       ForAll 双层循环的应用-生成九九乘法表

       Gallery的嵌套使用-展示乘法表

   ForAll函数-替代定义变量的两种方法

       方法一:使用集合来替代变量

       方法二:巧用Substitute和Concat函数

   示例:使用 ForAll 函数 给集合添加序号列


奇思妙想:ForAll嵌套循环生成九九乘法表


嘿嘿,虽然实际不会有人提出这样的需求,但可以通过这个有趣的小案例,来熟悉一下ForAll函数的用法,以及Gallery的不规则嵌套显示

ForAll的语法规则


ForAll(

   集合名 As 别名,

   // 这里写每次循环要操作的代码,多行代码用 ; 隔开

)


   


注意事项:


   1、通过别名.列名 来取每行的值

   2、ForAll中不允许定义全局/局部变量(后面讲如何解决)


ForAll 函数的基础使用 示例:


先做一些准备工作:


   // 假设有一个集合 colBasic

   Collect(

    colBasic,

    { Name: "ZhangSan", Age:18, Area:"HeBei"},

    { Name: "LiSi", Age:21, Area:"JiNan"}

   );


       



示例:


ForAll(

colBasic As item,

Collect(

colData,

{

Name: item.Name,

WorkPlace: item.Area

}

)

)


   


然后你就会获得这样一个集合,这就是ForAll函数的初步使用:

ForAll循环固定次数 (Sequence函数)


这里介绍一个新的函数,Sequence函数,下面是它的使用示例:

Sequence(数量,从几开始,增量) //默认从1开始,默认增量为1

Sequence(6) 等于 Sequence(6,1,1) 相当于:

[1,2,3,4,5,6] (实际返回的是表,形如[{Value:1},{Value:2}] )

Sequence(6,6,-1) 相当于:

[6,5,4,3,2,1]

ForAll循环固定次数示例:


ForAll(

   Sequence(3,5,-1) As Seq,

   Collect(

       colNumber,

       {Number: Seq.Value + 10}

   )

);


   


然后就会返回这样的集合:

ForAll 双层循环的应用-生成九九乘法表


怎么收集九九乘法表的集合呢,那我们就需要先分析一下


   i=1

   j=1

   value: 1 * 1 = 1


   i=1,

   j=2,

   value: 1 * 2 = 2

   i=2,

   j=2,

   value: 2 * 2 = 4


   从上述排列可以分析出:

   j 的规律是 从1到9,

   i 的规律是 对于每个 j 的值,需要循环从 1到 j 次

   也就是说 j=1,i=1 ; j=2, i=1,i=2; j=3,i=1,i=2,i=3 以次类推


根据我们分析的规律,就可以对应地写嵌套循环了


代码如下:


Clear(colMult);

ForAll(

   Sequence(9) As j,

   ForAll(

       Sequence(j.Value) As i,

       Collect(

           colMult,

           {

               i: i.Value,

               j: j.Value,

               value: i.Value&"*"&j.Value&"="&(i.Value*j.Value)

           }

       )

   )

)


    


返回值:

这里展示的是,嵌套固定次数的ForAll循环,事实上,实际应用中更多的是通过特定的集合进行循环,原理是一样的,例如:


ForAll(

colAll As Item,

ForAll(

Gallery1.AllItems As X,

Patch(

某表名,

{

列1: Item.列A,

列2: X.列B

列3: X.Label1.Text

}

)

)

);


   


实际的逻辑还是需要根据应用场景进行自定义。


   这里还想要强调的一点是,我们可以使用Gallery.AllItems作为循环的集合,不仅可以取到Gallery中集合的值,还可以获取其控件的值,如 X.Label1.Text


Gallery的嵌套使用-展示乘法表


效果图:

我们需要展示的是9行9列的表,但每行展示的数目不同。


我们已经收集了colMult的集合,包含 i,j,value 三列,那我们就需要通过 i 和 j 的值来获取到每个位置应该展示的 value 的值


1、在屏幕中插入一个 垂直空白库(Blank vertical gallery)

Gallery的Item值为:Distinct(colMult,j)

2、在垂直空白库中插入一个Label标签

Text的值为: ThisItem.Value (这个标签的名字我把它设置为 labJ )


   这个标签就是行数,它是必要的,因为我们需要获取每行的值,但它并不需要展示,Visible属性可以设置为false


3、在垂直空白库中 嵌入 一个水平空白库(Blank horizontal gallery)

Gallery的Item值为:Distinct(colMult,i)

4、在水平空白库中插入Label标签

Text的值为:


LookUp(

   colMult,

   i=ThisItem.Value && j = Value(labJ.Text)

).value


    


树状窗格如下所示:

解析:


   这里需要根据垂直空白库的 j 值,和水平空白库的 i 值,来查询到每一项的 乘法算式。


   在Gallery中我们可以通过 ThisItem.列名 来获取值,但这种嵌套的情况下,我们很难获取到外层Gallery的 ThisItem的值,所以我们在第二步添加了一个 Label标签,命名为 labJ ,用标签来获取到外层 Gallery的值


ForAll函数-替代定义变量的两种方法


前面说了,ForAll函数中是不能定义变量的,但我们使用ForAll函数的时候,根据实际应用场景可能会有通过变量来进行逻辑判断的需求,那我们只能曲线救国,用其他方式来达到类似的效果

方法一:使用集合来替代变量


把需要设置的变量设置成集合。例如 统计 colAll 集合 A列 的和:


// 原始数据

Clear(colAll);

Collect(

   colAll,

   { Name: "ZhangSan", Age: 18},

   { Name: "LiSi",Age: 21},

   { Name: "WangWu",Age: 25}

);

// 变量初始化

ClearCollect(

   colConfig,

   {varNumber : 0 }

);

// 统计年龄大于18岁的有多少人

ForAll(

colAll As Item,

If(

Item.Age>18,

Patch(

colConfig,

First(colConfig),

{

varNumber:  First(colConfig).varNumber + 1

}

)

)

)

// 之后就可以使用 First(colConfig).varNumber 来获取变量的值了


  


方法二:巧用Substitute和Concat函数


示例:

当所有项的Radio都不为空的时候,才允许提交数据,如下图

(为了方便测试,后面使用Collect函数来替代Patch/SubmitForm之类的操作)

组件的结构是这样的:

如果我们像下面这样写,逻辑就会是,循环时遇到空值时Notify,而其他的非空值会Collect;

但我们的需求是,所有都非空时才Collect


ForAll(

   Gallery1.AllItems As item,

   If(

       IsBlank(item.Radio1.Selected.Value),

       Notify("存在空值"),

       Collect(col,{item: item.Radio1.Selected.Value,id:item.Label9})

   )

)


   


所以下面使用Substitute和Concat函数组合,作为判别条件,直接绕开在ForAll中直接判断


   其实本质上就是把所有的选项值合并成一个文本,再用替换函数将不同的选项替换掉,通过处理后的文本长度,来实现各种判断


Set(

   varCount,

   Len(

       Substitute(

           Substitute(

               Concat(

                   Gallery1.AllItems,

                   Radio1.Selected.Value & ""

               ),

               "原创",

               "0"

           ),

           "转发",

           "1"

       )

   )

);

If(

   varCount = Gallery1.AllItemsCount,

   ForAll(

    Gallery1.AllItems As item,

    Collect(col,{item: item.Radio1.Selected.Value,id:item.Label9})

   ),

   Notify("存在空值")

);


    


当然了,如果我们想要实现一个功能,我相信可能有很多种不同的方式,这只是其中之一,

只是总结在这里给大家做一个参考

示例:使用 ForAll 函数 给集合添加序号列


假设有一个集合colAll,内容如下


Clear(colAll);

Collect(

   colAll,

   {Name: "ZhangSan", Dept: "IT"},

   {Name: "LiSi", Dept: "R&D"},

   {Name: "WangWu", Dept: "Sales"}

);


   


收集一个新的带序号的集合:


// 初始化先添加一个序号为0的数据,之后插入的数据,在0的基础上递增

ClearCollect(

   colnew,

   {

       No: 0,

       Name: "",

       Dept: ""

   }

);

ForAll(

   colAll As item,

   Collect(

       colnew,

       {

           No: Last(colnew).No + 1,

           Name: item.Name,

           Dept: item.Dept

       }

   )

);

// 把最初 No为0 的那条辅助信息删除

RemoveIf(colnew, No = 0);


    


效果: