プロが教える店舗&オフィスのセキュリティ対策術

 初めまして私はVB6.0の初心者でVB6.0について勉強しています。現在以下のようなiniファイル操作について分からないことがあります。

・プログラム内容

テキストボックスにログインID(例えばenshu)を入力しOKボタンを押して、iniファイル(例えばrenshu.ini)にある情報と照合してもしiniファイルに無かったら「ログインできません」というメッセージボックスを出すプログラム。

条件
・フォームにテキストボックス(Text1.Text)とコマンドボタン(OKボタン)がある
・Iniファイルの形式(renshu.ini)
IDNO(セクション名)
OK_ID(キー名)1 = “enshu”(ログインID)
OK_ID(キー名)2 = “ren”(ログインID)
OK_ID(キー名)3 = “shu”(ログインID)
上のような形式が不特定多数ある
・Iniファイルの保存場所
c:\work\renshu.ini

私の場合以下のように書きました。
Private Sub OK_Click() 'OKボタンがクリックされたら

If  Text1.Text <> GetIniString("IDNO", "OK_ID", "c:\work\renshu.ini") Then '入力したログインIDがiniファイルに無い場合
'メッセージ表示
MsgBox "ログインできません"

End If
End Sub
としましたがメッセージボックスが表示されません。なぜなのでしょうか。教えてください。宜しくお願いいたします。

A 回答 (13件中1~10件)

もし、何人だろうが挙げられている方法で処理するなら、例えば…



Dim i as Integer 'カウンタ
Dim tmpID as String 'IDテンポラリ
Dim idExists as Boolean 'ID存在フラグ

idExist = False 'ID未発見状態に
i = 0 'カウンタ初期化
Do
 i = i + 1
 tmpID = GetIniString("IDNO", "OK_ID" & CStr(i), "c:\work\renshu.ini")
 'Iniにキー値が存在しなかった場合はGetIniStringの戻りが""になるとして、
 'その場合は処理終了とする
 If tmpID = "" Then Exit Do
 '入力がIniのIDにヒットしたらフラグを立ててループから抜ける
 If Text1.Text = tmpID Then
  idExists = True
  Exit Do
 End If
Loop

'ループ後にIDが未発見ならメッセージ出力
If Not idExists Then
 MsgBox "ログインできません"
End If

…こんな感じので どうでしょ? テストはしてませんが…
これの前提条件として、OK_IDn の n は、必ず1から連番で存在しなければいけません。
(抜け番号は存在してはならない)
また、必ずログインIDは1文字以上登録されていなければいけません。
(抹消とかの対応のために、IDとして使用不可な文字を決めておいて、
 その文字を抜け番の判定に使う、なんて方法も考えられますが)

あと、上のソースではインデントに全角Space使ってますので変換してください。
でも…あまり多くなるようでしたら、やっぱりDBの使用をお勧めしますね。
管理大変ですし。
    • good
    • 0
この回答へのお礼

 K-Sogacchiさん、ご回答ありがとうございます。
あと確認の意味で、質問があります。宜しくお願いします。

>Dim i as Integer 'カウンタ
このカウンタとはOK_IDn のnをさしているのでしょうか。

>Dim tmpID as String 'IDテンポラリ
このIDテンポラリとはどういうことでしょうか。テキストボックスに入力したIDが一時的に保存状態になっているということでしょうか。

>idExist = False 'ID未発見状態に
これは、入力したIDがiniファイルに無かった場合という考え方で合っているでしょうか。

初歩的な質問ですみません。

お礼日時:2008/05/12 10:45

たびたびすみません、No.7ですが、念のために補足を。


当然ではありますが、No.12のように処理を行う場合、ユーザIDに
「not found」は設定できません(汗)。
厳密に言えば、プログラムの「穴」になりますので、頭の片隅に
入れておいてください。
あと、…何も考えずに答えだけ書いてしまいましたが、なぜ32767まで
止まらずにカウントして、挙句にエラーが出たのか、No.12に書いた内容を
踏まえてコードを読めば判断できるとは思いますので、頑張って考えてみてください。
    • good
    • 0
この回答へのお礼

 色々分かりやすい解説をして頂きありがとうございました。おかげで助かりました。

お礼日時:2008/05/12 17:03

再びNo.7です。


すみません、最初の方で、見つからなかった際の文字列について言及してたんですね。
んでは、以下の部分は、

'Iniにキー値が存在しなかった場合はGetIniStringの戻りが""になるとして、
If tmpID = "" Then
Exit Do 'その場合は処理終了とする
End If

以下に変えてください。

'Iniにキー値が存在しなかった場合はGetIniStringの戻りが"not found"になるので、
If tmpID = "not found" Then
Exit Do 'その場合は処理終了とする
End If

…あと、今回の場合はたぶん有り得ないとは思いますが、あまりにIniに登録されている内容が
多くて、32767件を超えていると、同じようなエラーになります。
これは、Integer型が32767までしか対応していないためなので、そういう場合は
カウンタや関連する変数をLong型に変更する等の対応が必要になります。
データ型は、細かい事は覚えなくてもいいけど概念だけは理解しないと、
後できっと泥沼にはまりますよ。
    • good
    • 0

No.7です。


>このカウンタとはOK_IDn のnをさしているのでしょうか。
そうです。CStrで文字列にして連結することにより、調べるキー値を設定しています。

>このIDテンポラリとはどういうことでしょうか。テキストボックスに入力したIDが一時的に保存状態になっているということでしょうか。
いえ、そうではありません。
GetIniStringで取得した文字列を、ループ中の 後の処理で複数回使用するので、
わざわざGetIniStringを複数回発行しないよう、1回発行したらその結果を
憶えておくためのテンポラリです。
この辺は、ソースの「書き方」レベルの話ですね。人によって多少書き方は
変わる可能性がありますが…

>これは、入力したIDがiniファイルに無かった場合という考え方で合っているでしょうか。
いえ、該当行での処理は、そうではありません。
該当行では、Iniにあったかどうかを憶えておくための、ON・OFFのスイッチ
(一般的に「フラグ」という呼び方をすることが多いです)を、初期状態として、
まずOFFに(BooleanなのでFalseに)しています。
で、ループ中にIni内で発見されればスイッチをON(True)にしてループを抜け、
ループ中に発見されないまま終了条件(If tmpID = "" Then Exit Do の部分)に達したら
スイッチがONにならない(Falseのまま)でループを抜けるわけです。

この手の処理方法は、私の中では常套手段なんですが… たぶん慣れれば分かりやすいと思いますよ。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
あともう一つ質問があります。
下のプログラムを実行しました。具体的にはテキストボックスにIniに無いID(例えばabcd)を入力して実行させたら「実行時エラー'6':オーバーフローしました」という警告表示が出て、デバッグするとi=i+1の行が黄色になってしまいその行にカーソルを合わせると「i = 32767」と出ます。一体何が原因なのでしょうか。お知恵をお貸しください。宜しくお願いします。

Private Sub Command1_Click()


Dim i As Integer 'カウンタ
Dim tmpID As String 'IDテンポラリ
Dim idExists As Boolean 'ID存在フラグ

idExists = False 'ID未発見状態に
i = 0 'ID初期化
Do
i = i + 1

tmpID = GetIniString("IDNO", "OK_ID" & CStr(i), "c:\work\renshu.ini")
'Iniにキー値が存在しなかった場合はGetIniStringの戻りが""になるとして、

If tmpID = "" Then

Exit Do 'その場合は処理終了とする

End If

If Text1.Text = tmpID Then '入力がIniのIDにヒットしたらフラグを立ててループから抜ける

idExists = True
Exit Do

End If

Loop



If Not idExists Then 'ループ後にIDが未発見ならメッセージ出力


MsgBox "ログインできません"


End If


End Sub

お礼日時:2008/05/12 16:13

確かに、redfox63氏の指摘通り、私の書いたやり方は、特に行数が多くなると


レスポンスが悪くなるはずです。1000とか超えると現実的じゃないレスポンスに
なるかも…
理由は、(あくまで推測ですが)GetPrivateProfileStringが、内部的に
「単純に先頭からLine Inputで1行ずつ読みながら文字列検索する」という動作を
していると仮定すると、以下の形のIniだと…

[IDNO]
OK_ID1=xxx
OK_ID2=xxx
 :
 :
OK_ID100=xxx

…OK_ID1を見つけるのに、2行読む事になります。
OK_ID2だと3行です。OK_ID100は101行です。
となると、100行あったら、読むのは100行じゃなくて
2+3+4+……+101 行になります。
おまけに、GetPrivateProfileStringを発行するごとに、ファイルのOpen、Closeも
行っているはずですので、更に遅くなります。

GetPrivateProfileSection(これの存在は初めて聞きました…)で一気に取得するか、
Iniファイルといえど結局は基本的にただのテキストファイルなので、
自力で読みながら文字列解析するか、の方が、あくまでIniファイルを
使用するならば現実的なのかもしれません。
    • good
    • 0

K-Sogacchi氏の回答のように、Iniファイルをなめてやれば 1000人だろうと2000人だろうと可能です


ただ、レスポンスが悪くなったり無駄が多いのでより効率的に認証させたいならと思い#6の回答内容となります

毎回 GetPrivateProfileStringで検索するより
GetPrivateProfileSectionでセクションごとデータを取得して
改行などで配列に分割、この配列を検索する
といった手法もあるでしょう
    • good
    • 0

NO.7です。

すみません、バグがありました(汗)
idExist = False 'ID未発見状態に
ではなく、
idExists = False 'ID未発見状態に
ですね。
    • good
    • 0

一般的な話をすれば 100人とか照合しないといけないのであれば


照合用のIDとパスワードといった組み合わせで入力をさせるようにします
そうすれば GetIniStringの現在キーにしている ID_OKxxといった物が不要になります
つまりIDとして入力される "enshu"、"ren"、"shu"などをキーにして データのパスワードをGetIniStringで引き出すといった具合にします

もっと管理する人数が増えるのであれば データベースを使うように考えましょう
    • good
    • 0
この回答へのお礼

ご回答頂きありがとうございます。
 それではテキストボックスに入力したIDデータ1つとiniファイルにあるIDデータ全部(IDデータの数が10未満でもよい)を比較することは不可能なのでしょうか。お知恵をお貸しください。宜しくお願いします。

お礼日時:2008/05/09 15:25

> GetIniStringで取得したデータとText1.Textは同一ではありませんでした。


> 一体何が原因なのでしょうか。
単に『同一ではありませんでした』といわれても原因なんて分かりません
WinAPIのGetPrivateProfileStringでエラーになったのか、その他のロジックが悪いのか
実行した結果ssが『何々』でしたとか lngRetの値が『云々』でしたといった返答をしましょう
# われわれ回答者はあなたのすぐそばで見ているわけではありません

他の方も回等しているように
GetIniStringの引数garKeyの与え方がまずいため返り値が"not found"になっているのであろうと思います

garKeyに "OK_ID1"、"OK_ID2"、"OK_ID3"などを与えて検査するようにしましょう
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
Private Sub Command1_Click()

Dim ID As String 'iniファイルから文字列を取得する関数

ID = GetIniString-("IDNO", "OK_ID4", "c:\work\renshu.ini") '関数を変数IDに格納----★

If Text1.Text <> ID Then

MsgBox "ログインできません"

End If
End Sub
>garKeyに "OK_ID1"、"OK_ID2"、"OK_ID3"などを与えて検査するようにしましょう
GetIniString("IDNO", "OK_ID4", "c:\work\renshu.ini") のキー名の部分を"OK_ID1"、"OK_ID2"、"OK_ID3"という風に変更してテキストボックスに★と違うログインIDを入力した結果「ログインできません」とでました。ただGetIniString関数で取得できるデータはひとつだけで、iniファイルにあるログインIDが不特定多数(例えばiniファイルにログインIDが100個ある場合)と照合するときには不向きです。こういう場合GetIniStringの引数のキー名の部分をどのように表せばよいのでしょうか。ご教授ください。宜しくお願いします。

お礼日時:2008/05/09 13:56

前にも書いたんだけど、



GetIniString("IDNO", "OK_ID", "c:\work\renshu.ini")
     ↓
GetIniString("IDNO", "OK_ID1", "c:\work\renshu.ini")
GetIniString("IDNO", "OK_ID2", "c:\work\renshu.ini")
GetIniString("IDNO", "OK_ID3", "c:\work\renshu.ini")

なのでは?
"OK_ID"≠"OK_ID1"ですから…
それと、OK_ID1="AAA"のように記述すると、"も入ってしまうのでは?
いきなり比較しないで、他の方の回答のようにイミディエイトウィンドウに表示してみましょう。

Dim ID As String
ID = GetIniString("IDNO", "OK_ID", "c:\work\renshu.ini")
Debug.Print ID
If Text1.Text <> ID Then
・・・・
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!