[Powershell]Global Variable With Data Type データ型を指定してグローバル変数を定義する方法

# というのは例によってどこにも具体例がない
これは完全に書き忘れていましたが、Powershell5.1(64bit)で実験していますが、コメント欄でご指摘いただき、Powershell7でも同じであることが判明しました。
## グローバル変数自体は

```powershell
$Global:stringvarable
```

のように`$global:'をつけます。

もしくは
[about_scopes(powershell-5.1)](https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-5.1)

```powershell
New-Variable -Scope global -Name a -Value "One"
```

という場合もあります。しかし公式の解説にもDatetimeを使ったグローバル変数のサンプルありません。

## データ型を指定したPowershellのグローバル変数の例

```powershell
[System.String]::$global:vbCrLf ; $vbCrLf = "`r`n" 
[System.String]::$local:vbCrLf ; $vbCrLf = "`r`n" 
[System.String]::$Script:vbCrLf ; $vbCrLf = "`r`n" 
```

このように
`[Datatype]::$scope:variablename`
という形を取るようです。
`Script` `Local` のScopeでも定義できます
これで一応成功していると考えられる理由は、

```powershell
Get-Variables -Scope Global
```

で出力するとGlobal変数の一覧に現れるからです。

## 型指定すると、直接値が代入できない？
これは現在原因が不明ですが型指定を行う場合、データ型を指定しつつ、値を代入することはできないみたいです。
オプションの定義かバージョンの違いなのかもしれません。
もしくは、New-varibaleでもデータの型を指定する項目がないらしいので、もとから指定できないのかもしれません。
と書いていたのですが、実はありました。コメント欄を御覧ください。

### サンプルコードで比較
これはうまくいきますが、

```powershell
$global:DT = "2021/01/01"
```

こちらは失敗します。

```powershell
[System.DateTime]::$global:DT = "2021/01/01"
```
#### 回避策

```powershell
[System.DateTime]::$global:DT ; $DT = "2021/01/01" ;
```

とこのように型指定したあとに、代入するという方法を取ると成功します。もちろんこれ以外にもあると思います。
というかコメント欄でご指摘いただいたのですが、実はコロンがいらないようです。

## サフィックス（リテラル）もある
もっとも、Powershellも代入する値によって、データ型を指定されます。
ところで、なぜ型指定しなくてもいいし、公式でも型は厳密ではないのにデータ型を重視するのかというと、演算誤差対策のためです。
ただ、公式では、Decimalは128bit浮動小数点型になっています
[about_variables](https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_variables?view=powershell-7.1)
[数値リテラルについて](https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_numeric_literals?view=powershell-7.1)
また、Powershellの6であらたにリテラル文字が増えています。
[PowerShellを電卓として使う際のTips集](https://dev.classmethod.jp/articles/powershell-as-a-calc-tips/)

## Currency型はない
VBSをやっている人は知っているけどVBAでも十進型（固定小数点4桁付十進型）がなくて`CDec`を使っている。
これと同じように型を変換することができるが、CDECのようにデータの型まで変換することはできないらしい。

### 型変換
しかし、それが結構わかるわけがない

```Powershell
PS > "{0:C}" -f 1000.12356
¥1,000
```

しかもこのときは

```Powershell
 $varCur = {0:C4} -f 1000.12356
```

変数に代入してもCurrencyではなくStringになっている。




[Powershell基本](http://wiki.yottun8.com/?PowerShell+%E5%9F%BA%E6%9C%AC#k0afbd81)
[How-to: The -f Format operator](https://ss64.com/ps/syntax-f-operator.html)
公式のページはわかりにくい
[Use PowerShell and Conditional Formatting to Format Numbers](https://devblogs.microsoft.com/scripting/use-powershell-and-conditional-formatting-to-format-numbers/)
CがCurrencyとか書いているが、これはリテラルではなく、フォーマットの定義何である。
上記のような書き方は
Example 3A あたりから出てくる。
[PowerShell - Composite Formatting references (-f Operator) ](https://lazywinadmin.com/2016/08/powershell-composite-formatting.html)
一般的には`-f`演算子(Format Operator)として意識されている。

# まとめ

<OL>
<li> Powershellのグローバル変数にもデータ型を定義することが可能である
<li> ただし、同時に値を設定することはできなりらしい
<li> サフィックス（VBA等ではリテラル文字）を加えることで値を代入するときに決めることもできる。
<li> VBAのCurrency型（4桁固定小数点付き十進）はPowershellにはない
<li> それは型変換というかFormatでしかVBAの通貨型が表現できない。
<li> Decimalは128bit浮動小数点と公式はしている
<li> 今までリテラル文字のDも十進型と思っていたが違うのかもしれない。
<li> Powershell 6.2からリテラル、データ型が増えているので後方互換に注意。
</OL>

マイクロソフトが6.2とかで狙っているのはPythonみたいな技術計算に使ってもらうことらしい。
そんな暇があったらVBAから移植しやすいようにCurrency型を定義すべきではないのか。
なぜ常識的な手から打たないんだろう。他の言語と競争して勝ちたいなら、足元を固めて、VBAからの互換でもスムーズで事務処理でも使えることをアピールすべきなんですけどね。