Power Apps - 终于有人把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);

效果:
在这里插入图片描述

欢迎关注我的博客,与我一起学习,我将持续分享我的学习过程,我是 热爱学习的小翁同学~

  • 27
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值