我的问题基本上如下:

也就是说,我想根据“交易”列表更改数组中的某些值。

在图中,您只能看到 2 笔交易,但实际交易数量可能更多。

我已经为我的一半阵列找到了解决方案:

但是,在处理完所有交易后,我无法获得所需的最终数组。我有点迷茫。

任何提示都非常感谢

1

  • MAKEARRAY()可能FILTER()会有帮助。


    – 



6 个回答
6

您可以尝试MAKEARRAY()使用FILTER()功能。

=MAKEARRAY(ROWS(C5:F8),COLUMNS(C5:F8),LAMBDA(r,c,FILTER(J11:J12,(H11:H12=r)*(I11:I12=c),INDEX(C5:F8,r,c))))

0

无需使用任何辅助函数即可实现这一点LAMBDA(),这里有一个替代方法:


方法一:在单元格中使用公式C14

=LET(
     a, C5:F8,
     b, TOCOL(a),
     c, ROWS(b),
     d, COLUMNS(a),
     e, MOD((SEQUENCE(c)-1),d)+1,
     f, INT((SEQUENCE(c)-1)/d)+1,
     g, MMULT((f=TOROW(H11:H12))*(e=TOROW(I11:I12))*TOROW(J11:J12),{1;1}),
     h, WRAPROWS(IF(g=0,b,g),d),
     h)

对于上述方法,如果任何实例中有 0 作为新值,那么它将返回假阳性,正如先生已经提到的那样,因此也可以使用修改后的版本。

=LET(
     a, C5:F8,
     b, TOCOL(a),
     c, ROWS(b),
     d, COLUMNS(a),
     e, MOD((SEQUENCE(c)-1),d)+1,
     f, INT((SEQUENCE(c)-1)/d)+1,
     WRAPROWS(IFNA(XLOOKUP(f&"|"&e,
                           H11:H12&"|"&I11:I12,
                           J11:J12),b),d))

切换变量来查找每个变量返回的内容。

将其更改{1;1}为,如果是多个,则使用其他一些替代方案 –>

SEQUENCE(ROWS(J11:J12))^0

或者,

SEQUENCE(ROWS(J11:J12),,1,0)

方法二:我认为另一种粗暴的方法是使用XLOOKUP()IFNA()


=IFNA(XLOOKUP(B5:B8&"|"&C4:F4,H11:H12&"|"&I11:I12,J11:J12),C5:F8)

LET()与上述内容一起使用:

=LET(
     α, C5:F8,
     δ, SEQUENCE(ROWS(α)),
     ε, SEQUENCE(,COLUMNS(α)),
     IFNA(XLOOKUP(δ&"|"&ε, 
                  H11:H12&"|"&I11:I12, 
                  J11:J12), α))

• 方法三:使用REDUCE()

=REDUCE(C5:F8,J11:J12,LAMBDA(a,v,
 MAKEARRAY(B8,B8,LAMBDA(r,c,
 LET(L,TAKE(+H12:v,1),IF((r=@L)*(c=(@DROP(L,,1))),v,
 INDEX(a,r,c)))))))

• 方法四:使用MAP()

=LET(
     a, IF(SEQUENCE(,4),B5:B8),
     b, IF(SEQUENCE(4), C4:F4),
     IFNA(MAP(a,b,LAMBDA(x,y,
     XLOOKUP(1,(H11:H12=x)*(I11:I12=y),J11:J12))),C5:F8))

4

  • 1
    如果新值为 0,则方法一不起作用。


    – 

  • @rotaborif a这意味着它可能存在也可能不存在。你能预测或说新值为 0 的可能性有多大?嗯,它可以被修改。此外,我还发布了另一种方法。


    – 

  • 我将数字视为值,并且不认为值为 0 有任何限制。因此,我们不应排除 0。


    – 

  • 2
    我会认真分析和收集像您这样的有经验的用户提供的最佳技巧,但有些技巧看起来有些多余。SEQUENCE(ROWS(J11:J12))^0就是其中之一。它可以被清晰的表达SEQUENCE(ROWS(J11:J12),,1,0)或取代MAKEARRAY(ROWS(J11:J12),,LAMBDA(I,j,1))


    – 


=IFNA(XLOOKUP(ROW(B5:E8)-4&-COLUMN(B5:E8)+1,H11:H12&-I11:I12,J11:J12),B5:E8)

输入范围的行号减去校正值(在本例中为4 ROW(B5:E8)-4)从 1 开始。

对于列 #,适用相同的逻辑,但因为我在前面添加了一个减号(作为分隔符),所以我们需要添加更正(+ 而不是 -): -COLUMN(B5:E8)+1

10

  • 通过分隔符来加入搜索条件是一个聪明的技巧。


    – 

  • 2
    @Rotabor 我发现 @MakukhBhattachayra 的第二种方法的逻辑几乎相同(或者说我的与他的相同,因为他在我之前发布)。他利用了辅助单元格,结合我的单元格,可以实现:=IFNA(XLOOKUP(A5:A8&-B4:E4,H11:H12&-I11:I12,J11:J12),B5:E8)


    – 


  • 1
    ROW()并且COLUMN()不能在数组中工作,我错了吗?


    – 

  • 1
    但这不是数组,只是单元格引用。尝试使用实际数组,我认为这是不可能的,因为在这种情况下你处理的是元素而不是单元格。


    – 

  • 1
    也许我只是在术语方面感到困惑,但 OP 提到了一个数组,但显示了一个范围。这两者并不相同。


    – 

对于旧版本的 Excel:

=IFERROR(
INDEX($A$1:$E$4, ROW(E4)-ROW($A$1)+1, COLUMN(E4)-COLUMN($A$1)+1) +
SUMPRODUCT(($G$2:$G$3=(ROW(E4)-ROW($A$1)+1)) * ($H$2:$H$3=(COLUMN(E4)-COLUMN($A$1)+1)) * ($I$2:$I$3 -
INDEX($A$1:$E$4, ROW(E4)-ROW($A$1)+1, COLUMN(E4)-COLUMN($A$1)+1))),
INDEX($A$1:$E$4, ROW(E4)-ROW($A$1)+1, COLUMN(E4)-COLUMN($A$1)+1))

另一种方式,

  • 逐行处理源代码REDUCE("Mapped", r_indices
  • 如果有映射,则映射该行
    IF(IFNA(XMATCH(r, in_row), FALSE), map_row(r), CHOOSEROWS(src, r)
=LET(src, C5:F8, mapping, I6:K7, in_row, INDEX(mapping, , 1),
  r_indices, SEQUENCE(ROWS(src)), c_indices, SEQUENCE(, COLUMNS(src)),
  map_row, LAMBDA(r, MAP(c_indices,
    LAMBDA(c, LET(
      in_rows, FILTER(mapping, in_row = r),
      XLOOKUP(c, INDEX(in_rows, , 2), INDEX(in_rows, , 3), INDEX(src, r, c)))))),
  DROP(REDUCE("Mapped", r_indices, LAMBDA(acc,r,
    VSTACK(acc, IF(
          IFNA(XMATCH(r, in_row), FALSE),
          map_row(r),
          CHOOSEROWS(src, r)
        )))),1))

公式为C14

=LET(i,C5:F8,MAKEARRAY(ROWS(i),COLUMNS(i),LAMBDA(r,c,XLOOKUP(TRUE,BYROW(H11:I12=HSTACK(r,c),AND),J11:J12,INDEX(i,r,c)))))