質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.63%

【Excelマクロ】ファイルの最終文字取得・Excelの差分表示

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,348

forestfield

score 14

Excelのマクロについて2つ教えてください。

<1>
ボタンを押したら特定のセルに入力した値がcsvファイルの末尾に1行追記されるマクロを作っています。
csvファイルの一番最後の文字が改行コードでないと直前の行に続けて記入されてしまうのですが、これをチェックする場合
・一度読み取りモードでcsvファイルを開く
・ファイルの最終行までよみこむ
・最後の文字を確認する
・ファイルを閉じる
・csvファイルを追記モードで開く
・最後が改行コードじゃなかった場合、改行コードを追記する
・入力値を追記する
・ファイルを閉じる
という手順しかないのでしょうか?
もっとスマートな方法、理想的な方法はありますか?
FileSystemObjectにもTextStreamにもファイルの最後の文字を取得するなんて都合のいい関数は無いようでした。

<2>
複数のExcelファイルの差分を表示させるマクロを作る場合、使用者に分かりやすいのはどういった方法でしょうか。最新ファイルが他のファイルの内容とどう違うのかを分かりやすくさせたいです。
各Excelファイルのファイル名は「固定文字列_日付_時間」、シート数は1シート。
内容は列数、行数共に増減する可能性のある表です。
現時点では
・マクロブックと同階層にある当日日付のExcelファイルをDir関数で取得
・マクロブックに各Excelファイルをシート別にCopyしてフィルタを解除
・コピーしたシート名をコピー元ファイル名の時間にする
・最も列数のあるシート、行数のあるシートから比較範囲を決定
・最も新しい時間のシートを基準に1セルずつ他のシートと比較
・値が同じ場合は最新シートの該当セルを白くぬる
・値が違う場合は最新シートの該当セルを赤くぬり、対するシート名のコメントを付与
で考えています。
もっとスマートな方法、理想的な方法はありますか?

Excelのバージョンは2010です。
他に必要な情報があれば聞いてください。
宜しくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

<1> 
ファイルの最後の文字を取得するメソッドは単独ではありませんが、ファイルポインタを移動すればよいと思います。
ほとんど答えになってしまいますが、書いておきます。

Const ForReading = 1, ForWriting = 2, ForAppending = 8
const fname = "C:\Temp\testfile.txt" 
Dim fso, stm
Dim fsize, bAddCrlf

Set fso = CreateObject("Scripting.FileSystemObject")
fsize = 0
If (fso.FileExists(fname)) Then
    fsize = fso.GetFile(fname).Size
End If
bAddCrlf = (fsize > 0)
If (fsize >= 2) Then
    Set stm = fso.OpenTextFile(fname, ForReading, True)
    ' 最後の2バイトがCRLFかどうかを読み込むため、ファイルサイズ-2バイトの位置に
    ' ファイルポインタを移動
    Call stm.Skip(fsize - 2)
    Dim last
    last = stm.Read(2)
    bAddCrlf = (last <> vbCrLf)
    stm.Close
End If
Set stm = fso.OpenTextFile(fname, ForAppending, True)
If (bAddCrlf) Then
    Call stm.WriteLine
End If
Call stm.Write("Append Value")
stm.Close

ところで、この出力するCSVファイルは、最後の行に改行コードがあってはいけないのでしょうか?
また、このファイルは他の人やシステムが編集することがあるのでしょうか?
もし、両方クリアできるのであれば、WriteLineで出力しているだけでよいと思います。
(安全のためにロジックを組んでおくのは悪いことではないですが、プログラムは短いほうがバグが少ないです)

なお、Excelで一度開いて、閉じるという方法でも、一見問題ないように見えますが、
Excelの欠点として、CSVを開くと、前ゼロが落ちるという問題があります。
つまり、

000001,1


のようなデータは、

1,1


になってしまいます。
他のシステムにデータを取り込もうとする場合など、これが問題になることも多いです。

<2>
あまり良い方法は思いつかないですね。
ファイルの比較については、Office 2013にはツールが付属します。
元のロジックで、一度赤くしたセルは白く塗りなおしてはいけない気がします。

行の増減もあるということなので、かなり難しいかと思います。
行が途中で削除されたら、それ以降の行はすべて変更扱いになります。
なにか、キーとなる列があれば、行追加・削除もとらえることはできると思います。

あと、質問が複数のときは、分けたほうが良いと思いますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/09 20:05 編集

    回答ありがとうございます。
    Skipという関数は調べていた時に目にした事があるのですが、恥ずかしながらその名前のせいか末尾から先頭に向けて戻れるという発想に至りませんでした。参考になります。

    csvファイルについてですが、最終行に改行コード(だけ)があってもいいのかという事ですよね?それは「だめ」です。
    このcsvファイルを他のシステム(管轄外なので干渉不可)が読み込んで登録情報が更新(読み込んだcsvの内容に総入れ替え)されます。
    なので少しでもシステムの仕様に合っていないと、読み込みに失敗して一時的に登録情報が全て消えてしまう事もあります。
    csvファイルはやろうと思えば手動で編集出来てしまうので、万が一少し知識のある人によって手動で編集されてしまった場合を想定して少しでも対策をしておきたいです。

    >ファイルの比較については、Office 2013にはツールが付属します。
    他の回答者さんも教えてくれていましたが、実はExcelに比較機能的なものが(アドオン?が)あるのは目にしたことがあり、それは既に報告済みです。
    しかし、社内の規定で申請が必要になるらしく大概その手の申請受理は長期間になる(機能していない?)との事で、皆こういう時は自分で作るという環境にあります。

    比較ツールに関しては現状で利便性を求めるのは難しいという事を理解して貰っているので、
    >元のロジックで、一度赤くしたセルは白く塗りなおしてはいけない気がします。
    >なにか、キーとなる列があれば、行追加・削除もとらえることはできる
    こちらも参考にお伺いを立てながら質問文にある方式でゆっくり作っております。

    >あと、質問が複数のときは、分けたほうが良いと思いますよ。
    失礼しました!
    同一人物の質問が同時にいくつも上がっているのは不快かと思い、まとめてしまいました。以後気を付けます。

    キャンセル

0

<1>
csvファイルをExcelで開いて『上書き保存』しますと、最後に改行がない場合は、最後に改行が付いたと思います。それが一番手っ取り早いような感じがします。(違っていたらご容赦)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/07 13:11

    回答ありがとうございます。
    使用者さんには色々と難しい方が多く、できれば「値を入れてボタンを押すだけですよ~」という方式で行きたいと考えております。

    キャンセル

0

<1>
文章で書いたので、誤解をされたようですね。
私が言いましたのは下記のようなコードです。これで、csvの最後に(改行がなければ)改行が付加されると思います。

    Workbooks.OpenText Filename:="C:\temp\test.csv"
    Application.DisplayAlerts = False
    ActiveWorkbook.SaveAs Filename:="C:\temp\test.csv", FileFormat:=xlCSV
    ActiveWindow.Close
    Application.DisplayAlerts = True

ここまでで、
>・一度読み取りモードでcsvファイルを開く 
>・ファイルの最終行までよみこむ 
>・最後の文字を確認する 
>・ファイルを閉じる 
>・最後が改行コードじゃなかった場合、改行コードを追記する 
が可能です。

あと、改行の有無を判断するのであれば、(私なら)line inputして、最後の行がlen()=0ならば改行ありと判断して、(そうでない場合には)改行を付けてもいいかもです。

<2>
最近のExcelには、(私は使ったことがないのですが)どこかに、対照比較する機能があったと思います。それを使うのがスマートだとは思います。(これは、マクロでなく、ユーザー教育の範疇になってしまいますが。)

(2010にもその機能があるかは、不詳です。すみません。)

が、<1>もですが、『スマート』とか『理想的』と考えていらっしゃるのが、どういうことかによるかと思います。

ほかにも、こういう手もあるよ~みたいな回答が付くといいですね!

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/09 19:41 編集

    引き続きの回答ありがとうございます。
    完全に誤解をしておりました。
    後出しになってしまい大変申し訳ないのですが今回は「電話番号」を扱うため、他の回答者さんも指摘されている「先頭0抜け」になってしまうので参考までに止めさせて頂きます。
    回答を頂く前に自分なりに考えた結果・・・詳細な関数名などは忘れてしまったのですが、追記モードでcsvファイルを開いてファイルポインタの位置が0かどうかで判断しました。

    >『スマート』とか『理想的』と考えていらっしゃるのが、どういうことかによるか
    これは人によって考え方が違うだろうなと思い、色んな方法・拘り・知識を聞けたらなぁと思って書きました。
    例えば今回でいうと理論を尊重して一度「読取」で開くのか、結果が同じであれば「追記」で開いて対応するのか等もきになっていた所の一つです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る