VBAは「物事をより簡単に」するために背中の背後にある多くのことをしています。問題は、これらのことが戻って来て、後であなたをかむことです。
たとえば、宣言されていない変数です。 Option Explicit
が各モジュールの先頭に指定されていないと、VBAは宣言されていない変数を使用するコードをうまくコンパイルします。役に立った?タイプがの場合、が推測されます。しかし、代わりにVBAはオンザフライVariant
を宣言します。これは、あなたが何を入れても(そしてあなたが割り当てているものに合わせてそのタイプを変更します)。
a = UsedRange.Rows.Count
ここ
a
暗黙のVariant/Long
です。 、さらに良い
Dim a As Long
それに意味のある名前を与える:Long
整数として宣言
Dim usedRows As Long
usedRows = UsedRange.Rows.Count
を今すぐ楽しい部分:
Testvariable = Range("A1", "A" & a)
ここTestvariable
があります暗黙のVariant/Array
。どうして? VBAが見るのコードは次のようになります。
Testvariable = Range("A1", "A" & a).Value
そしてa
が.Value
は、複数の単一のセルを参照していることを、1
ではないでしょうので、 - Excelのオブジェクトモデルを使用すると、すべての値を含む配列を与えます指定された範囲の細胞であり、それはTestvariable
に含まれています。あなたは範囲だけではなく、それらの値を参照するためにTestvariable
を望んでいた場合
は、あなたがRange
オブジェクト変数を宣言し、Set
キーワードとそれを割り当てます:
Dim testVariable As Range
Set testVariable = ActiveSheet.Range("A1:A" & a)
お知らせここに明示的ActiveSheet
:それがなければ、コードはまったく同じことなので、なぜそれを入れますか?あなたはできるだけ明示ようになりたいので: - そしてそれはバグのさらに別のソース(ちょうどグーグル、「範囲エラー1004」、あなた」だ、修飾されていないRange
Cells
、Rows
、Columns
とNames
はすべて暗黙的にアクティブなワークシートを参照して呼び出しますスタックオーバーフローに関する何百もの質問があります)。
あなたは値その指定された範囲内のすべてのセルのを含むようにtestVariable
を意味している場合、あなたはこのようなtestVariable
を宣言し、割り当てますが:
Dim testVariable As Variant
testVariable = ActiveSheet.Range("A1:A" & a).Value
そして今、あなたはすべての値を含む配列を持っていますアクティブなワークシートの範囲"A1:A" & a
:それはあなたのコードが暗黙的に行うことです。
FirstNo = Left(Testvariable, 1)
だから今、私たちは「最初の数」をしたい、と私たちは、バリアント配列をオフにそれを読んでいます。
Left
(またはLeft$
)の機能は、VBA.Strings
モジュールの機能であり、文字列を処理することを意味します。 (暗黙的な型変換を使用して)他の型でも動作しますが、オブジェクト参照または配列を渡すと、それを変換する方法はわかりません.VBAは実行時エラーを発生させます。
testVariable
バリアント配列には、Variant
の値が含まれます。ほとんどのセルには、Double
浮動小数点値が含まれます。その他にはString
が含まれます。一部のセルにエラー値(たとえば#N/A
,#VALUE!
、または#REF!
)が含まれている可能性があります.VBAでは、このようなエラー値も暗黙的に変換できません。
セルの値を読み取る前に、にはを必ず入力する必要があります。 (1, 1)
こと
If IsError(testVariable(1, 1)) Then
Exit Sub ' cell contains an error; cannot process
If Not IsNumeric(testVariable(1, 1)) Then
Exit Sub ' cell doesn't contain a number; cannot process
End If
' now that we KNOW our value is a numeric value...
Dim firstNumber As Double
firstNumber = testVariable(1, 1)
お知らせ:そのためIsError
機能を使用できますか? testVariable
は1ベースの2D配列です(Option Base 1
の暗黙的なサイズの配列はRange
から取得する場合を除いて常に0ベースです)、最初の行/最初の列の値を読み取るには、インデックス(1, 1)
の値を読んでください。
しかし、それはあなたがやろうとしていることではありません。
は、だから私は、各値の最初の数に応じて、値のセットに接頭辞を追加しようとしていました。
「各値」とは、値を繰り返し処理する必要があることを意味します。ループがあることを意味します。
Dim i As Long
For i = 1 To a
'...
Next
それは私たちが望む「最初の数」ではない、それは我々がをループしているすべてのセルのfirstDigit
、です。ここで
If FirstNo(i,1) = "1" Then
あなたが扱っている種類のトラックを失ってしまった:FirstNo
はループが開始するので、その値はすべての反復で一定となります前を割り当てられていました。
あなたがこれを行うことを意味:今すべてが、それは何が起こっているのか確認するためにはるかに簡単だ、明示的で適切にインデントされる...そしてあなたがするVBAを必要とする理由、今、私は真剣に質問したいこと
Dim values As Variant
values = ActiveSheet.Range("A1:A" & usedRows).Value
Dim i As Long
For i = 1 To usedRows
If Not IsError(values(i)) Then
Dim representation As String
representation = CStr(values(i))
Dim prefix As String
If Left$(representation, 1) = "1" Then
prefix = "abc"
Else
prefix = "def"
End If
ActiveSheet.Range("B" & i).Value = prefix & representation
End If
Next
をその:
[B1] = IFERROR(IF(LEFT(A1, 1) = "1", "abc" & A1, "def" & A1), "")
数式をドラッグします。
関連はありませんが、コードが適切にインデントされていると、コードを読みやすく保守しやすくなります。あなたが持っている答えに 'If ... End If'と' For ... Next'が表示されます。あなたがそれを行う方法がわからない場合は、私の[Rubberduck](http://rubberduckvba.com/indexation)があなたのためにできることを見てみましょう。一貫してプロジェクト全体をインデントし、宣言されていない変数などを特定する)。 –