• 締切済み

VBA LENの使い方

Lenを使う際にStrings.Lenとしないとエラーとなる場合があります。 Lenを使う際にクラスを明記すればいいんだと理解しましたが、別の問題が発生しました。 ユーザー定義のバイト数を求めるときにStringsをつけるとエラーになります。(いかにエラーになるコードを記載しました。) (LenはLenBとしてもエラーになります) そもそも、 クラスを明記しないとLenが探せない場合があってエラーになると思っていましたが、違うのでしょうか? オブジェクトブラウザでLenを検索してもVBAのStringしか出てきません。 Type a aa As Integer bb As Integer End Type Dim b As a Sub test() Dim a As Integer b.aa = 100 a = Strings.Len(b) End Sub

みんなの回答

  • HohoPapa
  • ベストアンサー率65% (454/691)
回答No.4

もう一度聞きますが、 Type a  aa As Integer  bb As Integer End Type Dim b As a Sub test()  Dim a As Integer  b.aa = 10000  a = Strings.Len(b) End Sub このコードで a = Strings.Len(b) の結果が4になることを期待しているのであれば、 a = Len(b) と書けば済みます。 a = Len(b)が4になるのは Integer型の変数は、埋まっている数値に関係なく メモリー上2バイトを使い、 その変数が、  aa As Integer  bb As Integer と2つあるからです。 もし、5になることを期待しているのであれば a = Len(format(b.aa,"0"))  と書きます。 やりたいこと、具体的なコード、エラーとなるコードなどが が示されていないので、推測となりますが、 総じて、メモリー上で割り当てられるバイト数と 変数に格納されている文字数を混同して LENを使っていませんでしょうか。 https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/len-function が参考になるものと思います。

tanakanono
質問者

お礼

結果は4でよいのですが、 お聞きしたいのは、なぜStrings.Lenが通らない時があるのかです。 String.LenやVBA.Strings.LenはLenと同じだと思っていますが、質問に書いた条件下ではStrings.Lenが通りません。 引数の自由度が変化しているようですが、VBAコンパイラの設計者が変な処理を入れているんですかね?マニュアルに書いてない以上お手上げかもしれません。

  • unokwave
  • ベストアンサー率58% (966/1654)
回答No.3

VBAの正式なドキュメントとしては https://docs.microsoft.com/en-us/openspecs/microsoft_general_purpose_programming_languages/ms-vbal/d5418146-0bd2-45eb-9c7a-fd9502722c74 からダウンロードできますが、ここでダウンロードできるpdfの263ページに、VBA.Strings.Lenが唯一Lenメソッドとして存在します。 Web上には https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/len-function にVBA用のLenメソッド仕様が載っていますが、オブジェクト(クラス)名はなく、また引数型記述もないものの、動作仕様としては上記ドキュメントと変わりません。 メソッドを使う場合、VBAではオブジェクト名を省略して記述できますが、もしメソッド名と同じ名前のオブジェクトが存在すると、恐らくそのメソッド名はオブジェクト名を省略して記述できないと思われます。 名前空間がどういう物か理解していればわかってもらえるでしょう。 そういうわけでStringsLenがエラーになるのならフルネームスペースであるVBA.Strings.Lenを使えば良いのではないでしょうか。

tanakanono
質問者

お礼

VBA.Strings.Lenでもエラーになります。 Lenのときだけ通ります。

  • HohoPapa
  • ベストアンサー率65% (454/691)
回答No.2

LENの引数に構造体の変数を指定した場合 その構造体の変数が使用するバイト数を返してくるわけですが a = Strings.Len(b) この結果がいくつになることを期待していますでしょうか? Stringsをつかったことがないのでよくわかりませんが Sub test2()  Dim a As Integer  b.aa = 10000  a = Strings.Len(b.aa)  MsgBox a   '5 となる End Sub Sub test3()  Dim a As Integer  b.aa = 10000  a = Len(b.aa)  '2となる  MsgBox a End Sub という動作から Stringsを使うと String型にキャストしてから文字数を数えているように思われます。 (単なる憶測で根拠はありません) a = Strings.Len(b) この結果が4になることを期待しているのであれば a = Len(b) と書けば済みますので、 課題はむしろ、 >Lenを使う際にStrings.Lenとしないとエラーとなる場合があります にあるんじゃないかと思います。

tanakanono
質問者

お礼

回答ありがとうございます。 int=Len("ABC")が通らない場合(PC)があります。確率的には2~5%くらいのPCで起きます。 さらに不思議なことに、もともと通っていたのに、別の関数やクラスをいじったことで、通らなくなることもあります。いつ通らなくなるのかわからないので手あたり次第Stringsをつけだしたのが始まりです。DateTimeクラスも同様のことが起きます。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.1

歴史的に古く、普通データの演算と(開発メーカーなどが作った)関数から学習し始めた小生(年寄り)は、関数=引数で指定したデータを自由(定義的な制約があるが)に変えられるそれを決まった処理してくれる、そして結果を返してくれる、サブルーチンを指すとの意味で理解してきました。サブルーチンは処理して、次の行に帰りました。それに対し関数は変数に結果を返してくれるもので、1つの関数名は決まった引数タイプを要求し、決まった処理をするものでした。 (その後「関数のオーバーライド」というのも現れ、たまげましたが。) 引き換え、質問者はVB.NET系やJavaを勉強してからVBAに入ったのではないですか。 そのうちオブジェクト指向のプログラム表記が流行になり、オブジェクト.メソッドの書き方が現れました。関数のLen(文字列)は文字数の意味で古くから使われ、オブジェクト.lenはメソッドのLENで、文字数のほかに、配列の要素数 を示すようなものもあらわれました.名前は同じでも、中身は,どういうものを返(定義する)すかは、自由(決めよう)なのです。 質問者は後者が本筋で、オブジェト部の表記のないものは、すべてオブジェクトの省略形という理解かもしれないが、そうではないものと思う。  この辺は、本やWEBでも明確に説明されていないように思いますし、難しいと思います。また知らなくても困りません。  WEBでも照会して、自分の思い込みに沿った、波長が合った解説に、出会われることを勧めます。検索語例 「関数とオブジェクトの違い」など。  もちろん、ここの回答でストンと理解ができるものが現れれば、ラッキーでしょうが。現れるかな。

tanakanono
質問者

お礼

回答ありがとうございます。 LenはVBAのStringクラスではないものもあるということでしょうか?オブジェクトブラウザに出てこない関数がデフォルトで読み込まれ、使えるということでしょうか???

関連するQ&A

  • VBAのプロシージャーと変数の名前の区別について

    VBAの初心者です。教えてください。 Sub ex() Dim a As Integer Dim b As Integer a = 2 a a, b MsgBox b End Sub Sub a(a As Integer, b As Integer) b = a End Sub 上記のプログラムを実行するとうまくいきません。VBAのプロシージャーと変数って同じ名前を使うとだめなのですか?教えてください。

  • エクセルVBAの次のコードの意味教えて下さい。

    Sub macro1() Dim a As Integer, b As Integer a = 1 b = 5 macro2 a, b MsgBox a + b End Sub Sub macro2(c As Integer, d As Integer) c = c * 10 d = d * 5 End Sub 答えは35と出ます。 よろしくお願いします。

  • VBAで行列を作る方法

    次のようなプログラミングで1,0,-1の要素で作られる3×3行列を全通り調べています。 この場合3の9乗通り調べることができます。 これを4×4や5×5行列など数を大きくして調べたいのですが、このプログラムを配列を使うなどして 簡単にできる方法を教えてください。 よろしくおねがいします。 Sub test() Dim a As Integer '行 Dim b As Integer '列 Dim c As Integer, i As Integer, j As Integer, d As Integer, e As Integer Dim 内積 As Integer, step As Integer Dim f As Integer, g As Integer, h As Integer, l As Integer, m As Integer, n As Integer, k As Integer, x As Integer Dim sum As Integer, total As Integer Dim aa As Integer, aaa As Integer, aaaa As Integer, bb As Integer, bbb As Integer, bbbb As Integer a = 3 '行 b = 3 '列 c = 0 内積 = 0 con = 0 sum = 0 tatal = 0 aa = 0 aaa = 0 aaaa = 0 bb = 0 bbb = 0 bbbb = 0 x = 0 For n = 0 To 2 For m = 0 To 2 For l = 0 To 2 For k = 0 To 2 For h = 0 To 2 For g = 0 To 2 For f = 0 To 2 For e = 0 To 2 For d = 0 To 2 '要素がすべて1 For i = 1 To a For j = 1 To b Cells(i, j) = 1 Next j Next i If bbbb = 1 Then Cells(a - 2, b - 2) = 0 ElseIf bbbb = 2 Then Cells(a - 2, b - 2) = -1 End If If bbb = 1 Then Cells(a - 1, b - 2) = 0 ElseIf bbb = 2 Then Cells(a - 1, b - 2) = -1 End If If bb = 1 Then Cells(a, b - 2) = 0 ElseIf bb = 2 Then Cells(a, b - 2) = -1 End If If aaaa = 1 Then Cells(a - 2, b - 1) = 0 ElseIf aaaa = 2 Then Cells(a - 2, b - 1) = -1 End If If aaa = 1 Then Cells(a - 1, b - 1) = 0 ElseIf aaa = 2 Then Cells(a - 1, b - 1) = -1 End If If aa = 1 Then Cells(a, b - 1) = 0 ElseIf aa = 2 Then Cells(a, b - 1) = -1 End If If total = 1 Then Cells(a - 2, b) = 0 ElseIf total = 2 Then Cells(a - 2, b) = -1 End If If sum = 1 Then Cells(a - 1, b) = 0 ElseIf sum = 2 Then Cells(a - 1, b) = -1 End If If con = 1 Then Cells(a, b) = 0 ElseIf con = 2 Then Cells(a, b) = -1 End If con = con + 1 Next d con = 0 sum = sum + 1 Next e sum = 0 total = total + 1 Next f total = 0 aa = aa + 1 Next g aa= 0 aaa = aaa + 1 Next h aaa = 0 aaaa = aaaa + 1 Next k aaaa = 0 bb = bb + 1 Next l bb = 0 bbb = bbb + 1 Next m bbb = 0 bbbb = bbbb + 1 Next n End Sub

  • マインスイーパーもどき(VBA)

    ExcelのVBAでマインスイーパーもどきを作っていますが、どうも上手くいきません。9が地雷で0が何もないと言うことです。以下、ソースです。 Sub mine() Dim minefield(11, 13) As Integer Dim i As Integer, a As Integer, b As Integer, x As Integer x = 0 Randomize For i = 1 To 20 a = Int(Rnd * 10) + 1 b = Int(Rnd * 12) + 1 If minefield(a, b) = 9 Then x = x + 1 i = i - 1 End If minefield(a, b) = 9 Next i MsgBox "地雷が" & x & "回重複" countMine minefield, 10, 12 showInt minefield, 10, 12 show minefield, 10, 12 End Sub Sub show(f() As Integer, h As Integer, w As Integer)  Dim a As Integer, b As Integer For a = 1 To 10 For b = 1 To 12 If (f(a, b) = 9) Then CStr(f(a, b)) = "*" If (f(a, b) = 0) Then CStr(f(a, b)) = " " Next b Next a End Sub If (f(a, b) = 9) Then CStr(f(a, b)) = "*" If (f(a, b) = 0) Then CStr(f(a, b)) = " " の部分でコンパイル時に 「コンパイルエラー:修正候補 識別子」 とでます。ヘルプを見てもよくわかりませんでした。 テキストが長すぎるので途中は省きました。 よろしくお願いします。

  • プログラミングVisual Basicの質問です。

    任意の数字を入力し、Len関数とMid関数を使って2進数を10進数に変換するというプログラムを作っているのですが、うまくいきません。 コードは Dim a  As Integer Dim b  As Integer Dim i  As Integer a = Val(TextBox1.Text) For i = Len(a) To 1 Step -1 If Mid(a, Len(a), 1) = "1" Then b += 2 ^ (i - 1) End If Next Label3.Text = b    End Sub 上記のものが作ったコードです。 問題点の指摘をよろしくお願いします。

  • Excel2007VBA時間の書式とLen関数

    ●質問の主旨 文字列の長さを返すLen関数の引数に 時間を設定すると戻り値が一定しないのはなぜでしょうか? また下記に示すように20や17などの数字がかえってくるの でしょうか? ●質問の補足 A1セルに入力されている時間が以下の通りだとします。 例1)1:11→20 例2)13:59→17 ●コード Sub test() Dim i as String i=Range("A1") Msgbox Len(i) End Sub 以上よろしくお願いします。

  • VBA 標準モジュールとフォーム

    ある標準モジュール内で生成した変数の値をフォームのコマンドボタンをクリックしたら表示されるプログラムはどうやってつくるのですか? 標準モジュール sub test() dim a as integer dim b as integer dim sum as string a=5 b=1 sum=a+b End sub フォームのコマンドボタンクリック Sub CommandButton1_Click() MsgBox sum End Sub 標準モジュールで計算した答えがフォームのコマンドボタンをクリックしたら答え6が表示されるようにしたいのですが、どうしたらできますか?

  • エクセルVBAについて質問です。

    エクセルVBAについて質問です。 ユーザーフォームのテキストボックスに数字以外を入力するとエラーメッセージが出るように関数を作ったのですが、 Private Function AA(objtextbox As MSForms.TextBox) As Boolean Dim A As String AA = False A = Trim(objtextbox.Text) If objtextbox.Text <> "" Then If IsNumeric(A) = False Then MsgBox "数値 Error", vbCritical With objtextbox .SetFocus .SelStart = 0 .SelLength = Len(.Value) End With AA = True End If End If End Function Private Sub textbox1_exit(ByVal cancel As MSForms.ReturnBoolean) cancel = AA(TextBox1) End Sub テキストボックス200近くある場合、1つ1つに Private Sub textbox1_exit(ByVal cancel As MSForms.ReturnBoolean) cancel = AA(TextBox1) End Sub と作っていかなくてはいけないのでしょうか? プロシージャ名に変数使おうとしたら上手くできませんでした。 どなたか助けてください。

  • VBAで関数を使うには?

    こんな感じだったとします。   A1      B1 2002/9/2 2002/9/3 2002/9/4 2002/9/5   : このB1にそれぞれの曜日を表示させるVBAを以下のようにしました。 Sub youbi() Dim i As Integer For i = 3 To 10 Cells(i, 3).Value = Weekday(Cells(i, 2), "aaa") Next End Sub もちろんエラーでした。 (メッセージは「型が一致しません」です。) そこで以下のように変更しました。 Sub youbi() Dim i As Integer For i = 3 To 10 Cells(i, 3).Value = "=text(Weekday(b3), ""aaa"")" Next End Sub するときちんと曜日が表示されたのですが、もちろん全部B3のセルの日付の曜日です。 ここを変数にするにはどうしたらいいのでしょうか? とっても簡単なことのように思えますが、意外とハマってしまって抜け出せません。 よろしくお願いします。

  • VBA 乱数と配列

    VBA 乱数と配列 配列(0)~配列(5)の一次元配列の中に、1から6までの数字を重複しないように入れたいのですが、 上手くいきません。 ご指導の程、お願いします。 Sub rndsys() Dim 配列(5) As Integer Dim サイコロ As Integer Dim カウントA As Integer Dim カウントB As Integer Dim フラグ As Integer For カウントA = 0 To 5 Do サイコロ = Int(Rnd(1) * 6) + 1 For カウントB = 0 To 5 If 配列(カウントB) = サイコロ Then フラグ = フラグ + 1 End If Next カウントB Loop Until フラグ > 0 配列(カウントA) = サイコロ Next カウントA MsgBox 配列(0) & vbCrLf & 配列(1) & vbCrLf & 配列(2) & vbCrLf & 配列(3) & vbCrLf & 配列(4) & vbCrLf & 配列(5) End Sub

専門家に質問してみよう