mid$について

解決


 2005-05-31 21:25:00  No: 122091  IP: [192.*.*.*]

Private Sub mnuFileOpen_Click()
    Dim sdata As String        'データ読み込み用
    Dim yn As VbMsgBoxResult   'メッセージボックス用
    Dim FileNum As Integer
    FileNum = FreeFile
    Dim s
    Dim t
    Dim r
    
     '保存の確認と保存処理  
    If Henkou = True Then  'データに変更あり?
        yn = MsgBox("まだ保存されていません。保存しますか。", vbYesNo, "保存確認")
        If yn = vbYes Then
            FileSave        '保存の処理を呼び出す
        End If
    End If
    '開くファイル名選択  
    On Error GoTo Err      'エラーが発生したらErrへ処理を移す
    CommonDialog1.ShowOpen '開くのダイアログを表示
    CommonDialog1.Filter = "DXF(*.dxf)|*.dxf|すべてのファイル(*.*)|*.*"
    Filename = CommonDialog1.Filename  'ファイル名を設定
    RichTextBox1.Text = ""                      'テキストを消去
    'データを読み込む  (c)
    Open Filename For Input As #FileNum 'ファイルを開く
    Do
        If EOF(FileNum) Then        'ファイルの終わり?
            Exit Do              'Do-Loopを抜け出す
        End If
        Line Input #FileNum, sdata 'データを1行(改行まで)読み込む
      r = r & sdata & vbCrLf
      s = InStr(r, "ENTITIES")
      RichTextBox1.Text = Mid$(r, s)
      
    Loop
    Close #FileNum                 'ファイルを閉じる
    Henkou = False   '変更なし
    Exit Sub         'プロシージャを抜け出す
Err:
    MsgBox "ファイルが開けませんでした。"
 
End Sub

とプログラムをうったのですがmid$のところでエラーがおきます
sではなくて数字を入れたら普通に表示されるのですが・・・
いったいなにがいけないんでしょうか?

編集 削除
ガッ  2005-05-31 21:39:56  No: 122092  IP: [192.*.*.*]

(´Д`;)<メモ帳にコピペしても見づらかったゾ…
            @mnuってメニューのサフィックスだったのか。

で、肝心の「質問」ですが、
これは単純な「デバックしてください」というお願いに帰着されます。
が、一応ヒント。
・エラーが起こったときのsの値は-1ではありませんか?
  →MSDNを探し回ったりして、例外の起こる可能性を全て捜査しましょう。
    →貴方が「トラップされると思っているエラー」は「ファイルが開けない」だけらしいですが、
      本当にそれだけですか?と言うことです。

編集 削除
ガッ  2005-05-31 21:45:02  No: 122093  IP: [192.*.*.*]

ぁ…良く見ると
> s = InStr(r, "ENTITIES")
となっているけど…InStrの引数ってさ…
※InStr([Start], [String1], [String2], [Compare As VbCompareMethod = vbBinaryCompare])
じゃないか…モウ馬犬 目 ぽ..._〆(゜▽゜*)

※ちゃんとヘルプ見ながら作(ry

編集 削除
魔界の仮面弁士  2005-05-31 22:27:29  No: 122094  IP: [192.*.*.*]

》蚊さん
> mid$のところでエラーがおきます
エラーが起きるのは、指定した変数の値に問題があるからです。

VBのメニューから [表示]-[ローカルウィンドウ]や
[表示]-[イミディエイト ウィンドウ]などを呼び出して、
エラー発生時に、Mid$関数にどのような値を
渡しているのかを確認してみましょう。

たとえば、変数 r に "ENTITIES" という文字列が含まれる場合と、
含まれない場合とで、どのように結果が変わってくるのかを
調べてみてください。


>   FileNum = FreeFile
FreeFile()関数の呼び出しは、『Openステートメントの直前』で
行うように心がけましょう。

たとえば、複数ファイルを同時に開く場合などは、
  F1 = FreeFile()
  F2 = FreeFile()
  Open FilePath1 For Input As #F1
  Open FilePath2 For Inout As #F2
のようにするのではなく、FreeFile()関数の呼び出しを
  F1 = FreeFile()
  Open FilePath1 For Input As #F1
  F2 = FreeFile()
  Open FilePath2 For Inout As #F2
のように、『それぞれのOpenステートメントの直前』で利用して
あげないと、エラーになってしまいますよね。


>    Dim s
>    Dim t
>    Dim r
変数を宣言する際には、必ず「As データ型」を付けるようにしましょう。


》ガッさん
> となっているけど…InStrの引数ってさ…
InStrの引数指定には、下記の3パターンがあります。
今回の場合は、パターン1 の使い方ですね。

1 :   InStr(元の文字列, 検索する文字列)
2 :   InStr(検索開始位置, 元の文字列, 検索する文字列)
3 :   InStr(検索開始位置, 元の文字列, 検索する文字列, 検索モード)

編集 削除
ガッ  2005-06-01 00:15:09  No: 122095  IP: [192.*.*.*]

> 魔界の仮面弁士さん
> InStrの引数指定には、下記の3パターンがあります。
> 今回の場合は、パターン1 の使い方ですね。

> 1 :   InStr(元の文字列, 検索する文字列)
> 2 :   InStr(検索開始位置, 元の文字列, 検索する文字列)
> 3 :   InStr(検索開始位置, 元の文字列, 検索する文字列, 検索モード)
情けないですが初めて知りました(orz
情報ありがとうございます。

※MSDNに軽く載っていました。
  …というかこのメソッドだけちょっと特殊…?
  ともかく、どうもありがとうございました(_ _

編集 削除
通ってみた  2005-06-01 02:30:04  No: 122096  IP: [192.*.*.*]

エラーの解決策は他の方々が書いてくださっているので、問題ないと思う

という訳で、オレは中身に関して少々
もし、ファイルの中身に"ENTITIES"という文字列が複数あるような仕様であるとすると、1回目の発見で処理が終了してしまうがよろしいだろうか?

もし、複数回同じような処理をしたいでのあれば、次のワードで調べてみるといいかもしれない

・Split

・UBound()

編集 削除
 2005-06-01 05:50:35  No: 122097  IP: [192.*.*.*]

みなさんありがとうございます。やってみます。

編集 削除
ねろ  2005-06-01 08:11:19  No: 122098  IP: [192.*.*.*]

私も突っ込みをすこし。。。。。

>Do
>   If EOF(FileNum) Then        'ファイルの終わり?
>        Exit Do              'Do-Loopを抜け出す
>   End If
>   Line Input #FileNum, sdata 'データを1行(改行まで)読み込む
これは普通
Do While Not EOF(FileNum)         
  Line Input #FileNum, sdata 
  ........
Loop
こうじゃない。

コメントが適切でない。
>Exit Sub         'プロシージャを抜け出す
こんなコメントは要らない。

>s = InStr(r, "ENTITIES")
>RichTextBox1.Text = Mid$(r, s)
ここになぜコメントが無いの?

>ENTITIES
ってもしかして、
ENTITLES
のこと。。。orz

編集 削除
魔界の仮面弁士  2005-06-01 09:36:24  No: 122099  IP: [192.*.*.*]

》ねろさん
> Do While Not EOF(FileNum)
私なら、Do Until EOF(FileNum) と書くかな……。


いずれにしても、
  Do
     If 脱出条件 Then
         Exit Do
     End If
     処理
  Loop
という書き方は、あまり一般的ではありません。>蚊さん

ねろさんが書かれたように、
  Do While 継続条件
     処理
  Loop
または、
  Do Until 終了条件
     処理
  Loop
という書き方の方が一般的かと思います。

ただし、
  Do
     前処理
     If 脱出条件 Then
         Exit Do
     End If
     後処理
  Loop
のような使い方であれば、さほど珍しくもありませんけれどね。


>> ENTITIES
> ってもしかして、
> ENTITLES
何故? ENTITIES(エンティティ)で良いのでは? (^_^;)
蚊さんが操作しているのは、Data eXchange Format File(*.DXF)ですよ。
# ちなみに、entity/entities には、「実体」という意味があります。

[R14 DXF Reference]
http://www.autodesk.com/techpubs/autocad/acadr14/dxf/

[DXF ENTITIES Section]
http://www.autodesk.com/techpubs/autocad/acadr14/dxf/entities_section_al_u05_c.htm

編集 削除
ねろ  2005-06-01 09:51:08  No: 122100  IP: [192.*.*.*]

>何故? ENTITIES(エンティティ)で良いのでは? (^_^;)
なるほど、これは失礼しました。orz

編集 削除
 2005-06-01 11:31:24  No: 122101  IP: [192.*.*.*]

失礼します、勝手に私の観点を言います。

>>      s = InStr(r, "ENTITIES")
>>      RichTextBox1.Text = Mid$(r, s)

もし、rは検索文字列に探し当てていないならば、取得したS値は0になっている。
Mid$(String,Start as Long,[Length])関数ですが、第二引数は1から使っていいです、0だならば、エラーを出たと思っています。
と言うことです

編集 削除
 2005-06-01 12:16:01  No: 122102  IP: [192.*.*.*]

魔界の仮面弁士さんの言ってくれたようにローカルウィンドウで調べたらsの値は0になってます>ガッさん  (↓のやり方だと)

      r = r & sdata & vbCrLf
      s = InStr(r, "ENTITIES")
      RichTextBox1.Text = Mid$(r, s)


そこで以下のように試したりしました
              ↓
text1.text=instr(r,"ENTITIES")
と打てば4590がでるのでて、その下で
RichTextBox1.text=Mid$(r,4590)とか打ちました。
そしたら、4590番目の文字列がでました。  
                              
でも、(r,4590)ところの4590に(text1.text)を入れた場合はtext1.textの値は0になってファイルを開くことはできませんでした。

編集 削除
ぶぶ  2005-06-01 13:16:31  No: 122103  IP: [192.*.*.*]

>text1.text=instr(r,"ENTITIES")
>と打てば4590がでるのでて、その下で
>RichTextBox1.text=Mid$(r,4590)とか打ちました。
>そしたら、4590番目の文字列がでました。  
                              
>でも、(r,4590)ところの4590に(text1.text)を入れた場合は
>text1.textの値は0になってファイルを開くことはできませんでした
すみません。意味がわからなかったです。
text1.text=instr(r,"ENTITIES")
としたら数値が出るのに
text1.text=instr(r,"ENTITIES")
RichTextBox1.text=Mid$(r,text1.text)
としたら出ないってことですか??

編集 削除
 2005-06-01 15:02:37  No: 122104  IP: [192.*.*.*]

はい>ぶぶ

編集 削除
 2005-06-01 15:02:42  No: 122105  IP: [192.*.*.*]

はい>ぶぶさん

編集 削除
ぶぶ  2005-06-01 15:19:13  No: 122106  IP: [192.*.*.*]

>text1.text=instr(r,"ENTITIES")

として数値が出た時のrと
>text1.text=instr(r,"ENTITIES")
>RichTextBox1.text=Mid$(r,text1.text)
とした時のrは確かに同じ内容が設定されているのでしょうか?
debug.print でイミディエイトに出力して確かめてみて下さい。

同じ内容が入っているとすると、なんででしょうね??

編集 削除
 2005-06-01 15:22:39  No: 122107  IP: [192.*.*.*]

FREEFILEやwhile文などいろいろアドバイスいただき有難う御座いました。LOOPのつける場所がまちがっていました。皆さんにはご迷惑をおかけしました。
あとrichtextbox1.textに表示されている内容を配列にすることってできるんでしょうか?教科書とか読んだんですが、内容が薄くてのってないのですが・・・なにか良い参考資料があれば、どなたか教えていただけませんか?

編集 削除
ねろ  2005-06-01 15:32:21  No: 122108  IP: [192.*.*.*]

Dim a() As String
a = Split(RichTextBox1.Text, vbCrLf)

編集 削除
魔界の仮面弁士  2005-06-01 15:45:58  No: 122109  IP: [192.*.*.*]

それと、コモンダイアログの使い方も間違っているようですよ。

> CommonDialog1.ShowOpen '開くのダイアログを表示
> CommonDialog1.Filter = "DXF(*.dxf)|*.dxf|すべてのファイル(*.*)|*.*"
 
ShowOpenしてから Filter をセットするのではなく、
Filter をセットしてから ShowOpenするようにしましょう。

編集 削除
 2005-06-01 21:19:14  No: 122110  IP: [192.*.*.*]

ねろさん魔界の仮面弁護士さん本当にありがとうございました。

編集 削除
通ってみた  2005-06-01 21:48:04  No: 122111  IP: [192.*.*.*]

だから  Split  を調べてみてと書いたのに・・・少し凹んだよ

編集 削除
 2005-06-02 15:35:08  No: 122112  IP: [192.*.*.*]

有難う御座います通ってみたさん

編集 削除