好的,我给了VBA solution,但这是一个使用相对较新的 LAMBDA 函数的纯 Excel 版本,没有 VBA。
请注意,我已经在 Code Review 上发布了一个 alternate version 和逗号分隔的 args PRINTF(mask, arg1, arg2, ...),但是我会尽量保持这个规范和最新,因为有新的更好的选项可用
为了实现这一点,我创建了一个带有签名printf(mask, tokensArray) 的命名函数,其中:
-
mask 是您要格式化的字符串,包含位置 {} 或索引 {i} 插值位置。
-
tokensArray 是要替换的一组值,以一维范围(行或列)、数组(硬编码或从函数返回)或单个值的形式提供。
... 并返回一个格式化的字符串。从像这样的单元格调用:
=printf("Some text '{1}', more text: '{2}'", A1:A2) //continuous 1D row/col
=printf("Some text '{1}', more text: '{2}'", {"foo","bar"}) //hardcoded array
=printf("Single Value {1}", "foo")
或使用位置参数(从左到右)
=printf("Some text '{}', more text: '{}'", A1:A2)
通过在名称管理器中输入这两个函数来定义它们(有关详细说明,请参阅LAMBDA function MSDN 文档,尽管我确定这个链接会失效...):
| Param |
Value |
| Name |
ReplaceRecursive |
| Scope |
Workbook |
| Comment |
Recursively substitutes {} or {i} with tokens from the tokens list, which it escapes one by one leaving } in the result string |
| Refers To |
=LAMBDA(mask,tokens,i,tokenCount, IF(i >tokenCount, mask, LET(token, INDEX(tokens,i),escapedToken,SUBSTITUTE(token,"}", "\}"),inIndexedMode,ISERROR(FIND("{}",mask,1)),substituted, IF(inIndexedMode, SUBSTITUTE(mask,"{"&i&"}", escapedToken),SUBSTITUTE(mask, "{}", escapedToken,1) ),ReplaceRecursive(substituted,tokens,i+1,tokenCount)))) |
=LAMBDA(
mask,
tokens,
i,
tokenCount,
IF(
i > tokenCount,
mask,
LET(
token,
INDEX(
tokens,
i
),
escapedToken,
SUBSTITUTE(
token,
"}",
"\}"
),
inIndexedMode,
ISERROR(
FIND(
"{}",
mask,
1
)
),
substituted,
IF(
inIndexedMode,
SUBSTITUTE(
mask,
"{" & i & "}",
escapedToken
),
SUBSTITUTE(
mask,
"{}",
escapedToken,
1
)
),
ReplaceRecursive(
substituted,
tokens,
i + 1,
tokenCount
)
)
)
)
| Param |
Value |
| Name |
printf |
| Scope |
Workbook |
| Comment |
printf(mask: str, tokensArray: {array,} | range | str ) -> str | mask: string to substitute tokens into e.g. "Hello {}, {}" or "Hello {2}, {1}" (1-indexed) | tokensArray: 1D range or array of tokens, e.g. "world" or {"foo","bar"} or A1:A5 |
| Refers To |
=LAMBDA(mask,tokensArray,LET(r,ROWS(tokensArray), c, COLUMNS(tokensArray), length, MAX(r,c), IF(AND(r>1, c>1), "tokensArray must be 1 dimensional", SUBSTITUTE(ReplaceRecursive(mask, tokensArray, 1, length), "\}","}")))) |
=LAMBDA(
mask,
tokensArray,
LET(
r,
ROWS(
tokensArray
),
c,
COLUMNS(
tokensArray
),
length,
MAX(
r,
c
),
IF(
AND(
r > 1,
c > 1
),
"tokensArray must be 1 dimensional",
SUBSTITUTE(
ReplaceRecursive(
mask,
tokensArray,
1,
length
),
"\}",
"}"
)
)
)
)
我敢肯定,Excel 的 LAMBDA 函数会有所改进,使编写起来更容易,但我认为这种递归方法现在很好。