[[20090619114605]] 『上書き保存する際、確認メッセージを表示したい』(ナカスミ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『上書き保存する際、確認メッセージを表示したい』(ナカスミ)

いつもお世話になっております。

現在、CSV出力するためのコードを書いているところなのですが、保存する際に何の確認メッセージも無く保存される状態となっています。

これを同名のファイル名が存在していた場合、「上書きしますか?」のようなメッセージで確認させたいのですが、どうすれば良いのでしょうか?

調べてみたのですが、まだわかっていない状態なので…何かヒントなど下さると幸いです。

Excel2007,XP


 >CSV出力するためのコードを書いているところ
 具体的にはどのような方法を使用して、ファイルを管理しているのでしょうか。

 EXCEL のアプリケーション機能? Open ? FSO?

 独自でファイルを開くのであれば、事前にファイルの有無を確認して、自分で
 メッセージを出すしかないと思います。
 (Mook)

Openです。コードは以下のようになっています。

Sub csv_button_Click()

    'Applicationオブジェクト取得
    Set xlAPP = Application

    Set objFolder = CreateObject("Wscript.shell")
    ChDir objFolder.SpecialFolders("DeskTop")

    '収容最終行の判定(Excel認知の最終行から上に向かってデータがある行を探す)
    colMax = Cells.SpecialCells(xlCellTypeLastCell).row
    Do While Cells(colMax, 1).Value = ""
        colMax = colMax - 1
    Loop

    'データが何も入力されてない場合、メッセージ表示
    If colMax < 7 Then
        xlAPP.StatusBar = False
        MsgBox "データを入力して下さい"
        Exit Sub
    End If

    'システム日付を格納(ファイル名に付加される)
    strUpdate = Format(Now(), "YYYYMMDD")

    '「名前を付けて保存」のフォームでファイル名の指定を受ける
    strFILENAME = xlAPP.GetSaveAsFilename(InitialFileName:="CSVデータ" & strUpdate, _
                  fileFilter:=cnsFILTER)

    'キャンセルされた場合、処理を抜ける
    If strFILENAME = "False" Then Exit Sub

    'FreeFile値の取得
    intFF = FreeFile

    'ファイルを開く
    Open strFILENAME For Output As #intFF

    delim = ","     '区切り文字のカンマ格納

    txt = ""        '初期化
    rec = 0

    '使用されたセル範囲分のデータを取得
    With ActiveSheet.UsedRange

            For col = 2 To .Rows.Count

                If .Cells(col, "C").Value <> "" Then

                    txt = txt & vbCrLf & Join$(Evaluate("transpose(transpose(" & _
                    .Rows(col).Address & "))"), delim)

                    'レコード件数
                    rec = rec + 1

                End If

            Next

    End With

    'データを出力
    Print #intFF, Mid$(txt, 3)

    'ファイルを閉じる
    Close #intFF
    xlAPP.StatusBar = False

    '出力完了メッセージを表示
    MsgBox "ファイルの出力が完了しました" & vbCr & _
        "レコード件数=" & rec & "件", vbInformation

====================

はい、ファイルの有無を確認して、自分でメッセージを出すしかないとは思うのですが…。

同名のファイルが存在するかしないか、というメッセージを出す方法はわかったのですが、その先に進められずにいます。

また再度、考えてみます。ありがとうございます!

(ナカスミ)


 どう先に進めないのか良く解りませんが。
 >Open strFILENAME For Output As #intFF
 Output Open 同じファイル名があれば、上書き。
 なければ新規に作成。
 尚、Output Open しただで、同名のファイルがある場合は、初期化されます。
 要するに中身は消えます。
 で、元に戻せません。(注意)
 BJ


 >   'キャンセルされた場合、処理を抜ける
 >   If strFILENAME = "False" Then Exit Sub
 の後にでも

    If Dir(strFILENAME) = StrReverse(Split(StrReverse(strFILENAME), "\")(0)) Then
      If MsgBox("上書き保存しますか?", vbYesNo) = vbNo Then Exit Sub
    End If

 と入れておくとか
 (momo)

BJさん

説明不足で申し訳ありません。ご回答、ありがとうございました!

momoさん

書いて下さったコードを元にして、自分の思っていた処理が出来るようになりました!

情けないのですが、書いて下さったコードの意味をまだちゃんと理解できていないので、これから調べてみたいと思います。

ありがとうございました!!

(ナカスミ)


 >ファイルの有無を確認して、自分でメッセージを出すしかないとは思うのですが…。
 >同名のファイルが存在するかしないか、というメッセージを出す方法はわかったのですが
 え、わかっていたんじゃないんですか?
 だから、この部分にはふれなかったんですが。
 BJ

再度質問で申し訳ないのですが、momoさんが教えて下さったコードの、

Thenの前にある (0) はどういった意味を持つのでしょうか?

===========

BJさん

わかった、というのは言い方を間違えました。

同名のファイルが存在するかしないかを判断するコードは他のところで見つけたのですが、そのコードを完璧には理解できておらず、そこからどう「上書き保存しますか?」に結び付けられるかがわからずにいました。

見つけたコードもmomoさんに教えて頂いた簡潔なコードでは無く、長いものだったので、他に何か方法やヒントが無いかと思い、質問しました。

失礼致しました。

(ナカスミ)


 まずは、記載したコードを分解して1つづつローカルウインドウで
 変数の中を確認するとわかりやすいかもしれません。
 以下のように分解してステップ実行(F8)で
 varBUFという変数の中身を見ながら実効してみてください。

 Dim strFILENAME As String
 Dim varBUF As Variant

 strFILENAME = "D:\abcd\Test.csv"
 varBUF = StrReverse(strFILENAME)
 varBUF = Split(varBUF, "\")
 varBUF = varBUF(0)
 varBUF = StrReverse(varBUF)

 (momo)

 上書き保存する際、確認メッセージ については、FSOを使う方法などもありますから、
 FSO(File System Object)のプロパティやメソッドをHelpで調べてみてください。

 コードを拝見して、私が気になったところは他の箇所です。

 Open strFILENAME For Output As #intFF

 上書き保存をする可能性もある仕様でいきなり指定されたファイル名でOutputモードでオープンすることは、
 非常に危険です。もし、オ−プン直後に電源が落ちたら、データがなくなってしまいます。

 この場合、例えば ファイル名として 「ichinose.CSV」という名前が指定されたら、

 ichinose.TMPとして、outputモードでオ-プンし、データを書き込む。

 ichinose.TMPをクローズする。

 既にあるichinose.CSVを削除する。

 ichinose.TMPを ichinose.CSVに名前を変更する。

 という手順でファイルを作成します。このような手順を踏んでおくと、
 何らかの原因でプログラムが途中で止まってしまってもファイルが保持される確率が高いですよね!!

 これは、OUTPUTモードでオープンするときに良く使われてきた手順です。

 検討してみてください。

 ichinose


momoさん

お礼を申し上げるのが遅くなってしまい、ごめんなさい。

momoさんに言われたとおりにコードを分解して見てみました。結果、以前よりも理解できたと思います!

私が質問した(0)というのは配列数で、StrReverseを二回しているのは一度文字列を逆に並び変えるとファイル名が並びの最初にきて、配列数(0)でそのファイル名を指定している…という解釈でよろしかったでしょうか。

自分の中では、これで納得がいったのですが…。

丁寧にご回答して頂き、ありがとうございました。

=====

ichinoseさん

ご指摘して頂き、ありがとうございます。

確かにichinoseさんの教えて下さった手順の方が安心ですね…。そう出来るように、考えてみます。ありがとうございました!

(ナカスミ)


 >私が質問した(0)というのは配列数で、StrReverseを二回しているのは
 >一度文字列を逆に並び変えるとファイル名が並びの最初にきて、
 >配列数(0)でそのファイル名を指定している…という解釈でよろしかったでしょうか。

 そのとおりで大丈夫です。
 文字列の扱い方は色々な手法があってコードを書いていても面白い部分でもあります。
 (慣れてくると逆に面倒なのですが)

 他にもファイル名を得る方法はいっぱいあります。
 最初からFSOを使っている場合はFSOでそのまま得られますし・・・
 今後、スキルアップとともに覚えていってください。

 (momo)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.