Power Automate: 文字抽出関数は Slice() がお勧め。Substring() よりも。

# 背景
Teams Connector は 28kB という Payload Limit がある。
自動転送なんかで、この制限に引っかかる場合には 28kb で削りたくなる
その際、以前は Substring() 使ってたんですが、以下のような入力文字数の長さを気にするのが面倒だった。
で、なんか他の方法ないのかと思ったら、Slice() が便利そうだったので知らない人におすすめ用に投稿

> substring('input text', 0, if( less( length( variables('input text')), variables('inputLength')), length(variables('input text')), variables('inputLength')))

variables('inputLength') == 28000

# 概要
- Slice() の利点
    - 入力文字列の長さを気にせず使える
    - Start Index で負数にすると、Right() の代わりになる
    - End Index を負数にすると、入力文字列の長さを基準に指定できる
- Substring() の利点
    - 長さ、という感覚で取得出来る

Slice() は Substring() と違い、開始、終了位置の指定なので、若干分かりにくい。
更に負数指定はなじみが薄いと思われるので、[**ここ**](#startend-index-の説明)で図示してます

# 詳細

- 入力文字列長を気にせず使える
    - Substring だと入力文字が不足していたりするとエラーになるので、if() で文字数調整必要で面倒
- Start Index で負数を指定すれば、Right() の代わりになる
    - [Slice(input, -3) == Right(input, 3)](#start-index-が負の場合-sliceinput--3--rightinput-3)
- End Index を負数にすると、入力文字列の長さを基準に指定できる    
    - [Slice(input, 3, -2) == Mid(Left(input, length -2), 3)](#end-index-が負の場合-sliceinput-3--2--midleftinput-length--2-3)

## Start/End Index の説明
Start/End Index が 0 から始まるのは、ソフトをかじったことがある人には馴染みが深いが、
Index の負の部分が分かりづらいので図にしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/6444f7ae-fd17-b030-47f3-77ca5780d048.png)

で、実際の例
### Start Index が負の場合： Slice(input, -3) == Right(input, 3)
> slice('HelloWorld', -3)

result: **rld**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/77d205b5-2b10-2119-7692-c7ba16d84d32.png)		


### End Index が負の場合： Slice(input, 3, -2) == Mid(Left(input, length -2), 3)
> slice('HelloWorld', 3, -2)

result: **loWor**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/8a1befcd-8176-bdd3-c76f-05952812c7db.png)

### Start/End Index が共に負の場合
> slice('HelloWorld', -5, -2)

result: **Wor**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/905c2c18-f806-37b5-1835-27c57a75e7d3.png)



# Document
理解する為には利用例を見るのが一番
[Slice()](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#slice) は利用例も豊富なので、確認がおすすめ
![2022-07-21_16h33_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/7840e6ea-ae6d-ea63-3035-f49bf48d7193.png)

[Substring()](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#substring) は、わかるでしょ？とでもいいたげに利用例は一点のみ。
![2022-07-21_16h34_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/c6db0014-8046-f0fd-0e54-8386b5faad88.png)

:::note warn
注意、に記述されているのが、入力文字から取得できない部分を指定した場合のエラーについて。
エラーが発生するとフローが止まるので、以下のようにして Start Index / Length を制御必要。
以下は、Length 制御の例。

> substring('input text', 0, if( less( length( variables('input text')), variables('inputLength')), length(variables('input text')), variables('inputLength')))
:::

## [Slice()](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#slice) の利用例の説明

### Start Index のみ指定
(StartIndex + 1) 文字目以降を取得

> slice('Hello World', 2) // Returns 'llo World'.
> slice('Hello World', 0) // Returns 'Hello World'.

### Start Index のみ指定：Start Index が入力文字数の長さを超えてる場合
存在しないので、空文字返却

> slice('Hello World', 30) // Returns ''.

### Start Index のみ指定：Start Index が負数の場合
(入力文字数の長さ - StartIndex) の位置以降の文字取得
== Start Index の絶対値分、右側から文字取得

> slice('Hello World', -2) // Returns 'ld'.

### Start Index / End Index 指定
(StartIndex + 1) 文字目から (EndIndex + 1) 文字目までを取得
長さ指定したい場合は、EndIndex = StartIndex + Length の指定

> slice('Hello World', 2, 5) // Returns 'llo'.

### Start Index / End Index 指定：Start Index  == End Index
取得無し

> slice('Hello World', 3, 3) // Returns ''.

### Start Index / End Index 指定：Start Index が入力文字数の長さを超えてる場合
存在しないので、空文字返却

> slice('Hello World', 10, 2) // Returns ''.

### Start Index / End Index 指定：End Index が入力文字数の長さを超えてる場合
(StartIndex + 1) 文字目から存在している部分のみ取得

> slice('Hello World', 6, 20) // Returns 'World'.

### Start Index / End Index 指定：End Index が負数の場合
(StartIndex + 1) 文字目から、入力文字数 - End Index の位置まで取得

> slice('Hello World', 3, -1) // Returns 'lo Worl'.


# あとがき
最初は、Excel Run Scripts でやろうとしてたけど、ちゃんと関数調べてよかった :laughing: 

# keyword
it is better to use 'Slice function' than 'Substring function'.