条件付きコンパイル 環境対応編纂命令 Const Directive And Conditional Compilation

#条件付きコンパイルは訳がおかしいかあっていない
たしかにIF文だが、環境に対応させるための場合分けである以上条件を付けているわけではなく条件に対応している。つまり環境対応と訳すべきではないかと思います。またコンパイル、コンパイラも編纂とすべきです。いろいろなルーチンをあつめて一つのファイルにしていくのは、本を作っているのに似ています。ですからまさに編纂なわけです。
そもそも原文もCompilationなのでどこがコンパイルなの?ほかでたぶんCompilationではないのでしょうけど。

https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/const-directive
[Understanding conditional compilation条件付きコンパイルを理解します。](https://docs.microsoft.com/ja-jp/office/vba/language/concepts/getting-started/understanding-conditional-compilation)
[#If...Then...#Else ディレクティブ](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/ifthenelse-directive)
※ディレクティブは命令にします

###構文

```visualbasic
#If expression Then
statements
[ #ElseIf expression-n Then
[ elseifstatements ]]
[ #Else
[ elsestatements ]]
#End If
```

|項目(Part) | 説明|
|:-------------:|:-------|
|expression |必須。 1 つ以上の条件付き編纂定数、リテラル、および演算子のみで構成された、True または False に評価される任意の式です。
|statements |必須。 関連付けられている式が True の場合に評価される Visual Basic プログラムの行または編纂命令です。 |
|expression-n |省略可能。 1 つ以上の条件付き編纂定数、リテラル、および演算子のみで構成された、True または False に評価される任意の式です。 |
|elseifstatements |省略可能。 expression-n が True の場合に評価される 1 つ以上のプログラムの行または編纂命令です。 |
|elsestatements |省略可能。 前の expression および expression-n がいずれも True に評価されなかった場合に評価される 1 つ以上のプログラムの行または編纂命令です。 |

#時々環境対応編纂命令がDebug欠陥検査のために使われるというのはなぜか
ドットネットフレームワークやC#でDebug Modeに使われるため
[方法: 追跡と欠陥検査のために環境対応編纂命令を使う方法](https://docs.microsoft.com/ja-jp/dotnet/framework/debug-trace-profile/how-to-compile-conditionally-with-trace-and-debug)

##Excel2003時代はVBAでも自作されていた
Excel 2003 VBA Programmer's Reference Chapter 7 "Writeing BulletProof Code"に残されている。

https://books.google.co.jp/books?id=A3cwmK0WvCwC&pg=PA133&lpg=PA133&dq=%23IF+MSDOS+then&source=bl&ots=bDmKyisAbY&sig=ACfU3U2nJM2smoaDnBtpMW5kgvrZo4ysjA&hl=ja&sa=X&ved=2ahUKEwiNl5WWp4bgAhXi-GEKHZmdBeoQ6AEwBnoECAEQAQ#v=onepage&q=%23IF%20MSDOS%20then&f=false

```visualbasic
Option Explicit
#Const  Tracing = True
#Const UseEventLog = False

Private Sub DebugPrint(Byval Source As String, Byval message As String)
#IF UseEventLog Then
#Else
Debug.Print "Source:= " & Source," message:= " & message
#End If
End Sub

Public Sub Trace(Byval Source As String, Byval message As String)
#IF Tracing Then
Call DebugPrint(source,Message)
#End If
End Sub
```

####Access97まではDOSV機のメーカーで使い分けていた

https://www.moug.net/tech/acvba/0020009.html

```
Sub Sample1()

#Const F_DOSV = True	' ← DOS/Vの場合：True、NEC PC98の場合：False にする

#If F_DOSV Then
    ' フロッピーデータをインポート（DOS/V）
    DoCmd.TransferText acImportDelim, , "t_履歴ワーク", "A:\Data.txt", False
#Else
    ' フロッピーデータをインポート（NEC PC98）
    DoCmd.TransferText acImportDelim, , "t_履歴ワーク", "C:\Data.txt", False
#End If

End Function
```

###If Then Else命令文と\#If...Then...#Elseの違い
\#If...Then...#Else 命令の動作は If...Then...Else 命令文と~~同じ~~動作は似ています。
####書き方が違い1行で書くことができない
\#If、#Else、#ElseIf、および #End If の各命令には単一行の形式がありません。したがって、これらの命令と同じ行に他のコードを含めることはできません。
#### Option Compareは影響せず Option Compare Textになる
Option Compare 命令文は、#If 命令と #ElseIf 命令の式には影響を与えません。条件対応編纂命令の式は常に Option Compare Text で評価されます。
##### これはなにを言っているのか? 
つまり大文字と小文字は区別されないという意味です。
#### 定義されていない定数はEmpty Option Explicitが効かない
>各評価の結果に関係なく、すべての式が評価されます。 したがって、式で使用されているすべての定数が定義されている必要があります。定義されていない定数は Empty として評価されます。

これが長所でもあり短所。Option Explicitが効かない

#### \#If...Then...#Else はコンパイル段階でコードを除外するが通常のIf...は除外しない
>実行可能なファイルにデバッグ コードが含まれないようにするためにも使用されます。 条件付きコンパイルで除外されたコードは、最終的な実行可能ファイルから完全に削除されるため、サイズやパフォーマンスに影響を与えることはありません。

ここがコメント欄でいただいた部分
###欠陥調査に使われる（上記の説明）
環境対応編纂命令は、通常、同じプログラムを異なるプラットフォーム用にコンパイルするために使用されます。 また、実行可能なファイルにデバッグ コードが含まれないようにするためにも使用されます。 Code excluded during conditional compilation is completely omitted from the final executable file, so it has no size or performance effect.環境対応編纂命令で除外されたコードは、最終的な実行可能ファイルから完全に削除されるため、サイズやパフォーマンスに影響を与えることはありません。

#\#Const 命令
編纂命令定数を定義する。
###構文

\#Const constname = expression
模組を超えることはできない。つねにPrivateでPublicにはならない。
コード内の位置に関わらず、常にモジュール レベルで評価される。
Visual Basic の 条件付きコンパイラ定数を定義するために使用されます。
Win64 VBA7といった環境対応編纂命令定数とリテラルが使える。

```visualbasic
#Const DebugVersion = 1 ' Will evaluate true in #If block. 
```

### 実験

```visualbasic
Option Explicit

#Const cnsEnv = True
#Const cnsMode = "Debug"
#Const cnsEnvDate = #1/1/2019#
#Const cnsDbl = 2#
#Const cndLng = 1&
#Const cndSgl = 1!
#Const cnsEnvInt = 3 'Integerの場合%は消える
#Const cnsEnvIntToobig = 2147483648# '数が大きいと自動的に#が付加され、倍精度になる


Sub test()
#Const InProEnv = True
#If cnsEnvDate = CDate(#1/1/2019#) Then
Debug.Print True

#End If
End Sub

Sub test2()
#If InProEnv = True Then
Debug.Print True
#End If
End Sub

```

数字は倍精度、単精度のリテラルを数字の後ろに付加できた。自動的に付加される場合もある。もちろん十進型＠はない。
またtestに書いたConstがTest2で作動する。
模組内のどこに書いても発動する。
通常のConstはプロシージャ内はプロシージャ内のみ有効なので違う。

###なぜかプロジェクトにも設定できる
https://screwandsilver.com/conditional_compilation/

```visualbasic
Sub test3()
'プロジェクトエクスプローラーを表示し、プロジェクトのプロパティを表示し、
' A=４:B=３:C=-1
' と入力 OK
#If A / 2 = 2 Then
Debug.Print True
#End If
#If CBool(C) = True Then
Debug.Print True
#End If
End Sub
```

####ただしプロジェクトレベルでは整数しか入らない
文字列、Bool(True/False)はエラーになる
####複数可能
半角コロンで区切ると複数が可能
#### 負の数をBoolで変換するとTrue/Falseができないことはない

###Win64などの定数は勝手に他の意味に変えられない
各評価の結果に関係なく、すべての式が評価されます。 したがって、式で使用されているすべての定数が定義されている必要があります。定義されていない定数は Empty として評価されます
定数は Visual Basic によって提供されているため、どのレベルでも、これらと同じ名前で独自の定数を定義することはできません。

###模組の冒頭でもSub Procedureでも使われる
```visualbasic
Sub SelectiveExecution()
#If conDebug = 1 Then
. ' Run code with debugging statements.
.
.
#Else
. ' Run normal code.
.
.
#End If
End Sub
```
##公式よりわかりやすい解説
実行環境の切り分けなどの例。

http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_800_500.html