[[20141116094527]] 『ディレクトリのパスについて』(minoru) ページの最後に飛ぶ

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

 

『ディレクトリのパスについて』(minoru)

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

ディスクトップの読込フォルダにある「a.csv」より
エクセルに読み込ませて、データを加工後に新規に「b.csv」を作成
するマクロを作成中です。

加工用のエクセルファイルと、「a.csv」ファイルは「読込」
フォルダにあります。

Open "C:\Users\minoru\Desktop\読込\a.csv" For Input As #1
マクロの冒頭に読み込ませるファイル名指定で上記のコードを記してい
ますが、このコードをどのパソコンで使用してもディスクトップの読込
フォルダより取得できるようにするため、「¥minoru」の部分を変更し
たいのですがどのようにすればよいのでしょうか?
欲をいえば、フォルダの場所や名前を変更しても同じフォルダにあれば
マクロが実行できるようにしたいです。

よろしくお願いします。

追記
また、最終的な目的は
「a.csv」の中身は件数は多いのですが列は10列で、加工する内容は、
最初の列にある文字列を20文字ずつに分けて「b.csv」の1−3列に
転記(60以上は無視)して、他の列はそのまま所定の列へ転記するだ
けです。
エクセルのVBAしか知らないので、エクセルを使用して加工していま
すが、ご存じであれば、何を勉強すれば同様なことができるか、具体的
な参考書名などとあわせてご教示いただければ幸甚です。

< 使用 Excel:Excel2003、使用 OS:WindowsXP >


 特殊フォルダのパスの一例です。
 ↓はデスクトップのパスです。

 CreateObject("WScript.Shell").SpecialFolders("Desktop")

 他にも「特殊フォルダ パス」で検索したら見つかると思います。
(カリーニン) 2014/11/16(日) 11:20

 「ディスクトップ」
 ↓ですね。
 「デスクトップ」

 用語はしっかり覚えてないと他人に聞いたりネット検索するときに不便ですよ。
(カリーニン) 2014/11/16(日) 11:22

 参考までに。

http://ja.wikipedia.org/wiki/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97
(カリーニン) 2014/11/16(日) 11:25


 '----------------------------------------------------------- 
 Option Explicit

 Private Declare Function SearchTreeForFile Lib "imagehlp.dll" _
    (ByVal RootPath As String, _
     ByVal InputPathName As String, _
     ByVal OutputPathBuffer As String) As Long

 Private Const MAX_PATH = 512
 Private Const MAX_PATH_PLUS1 = MAX_PATH + 1

 'デスクトップの\読み込み\フォルダにあるが、ユーザー名が都度変わるのを
 '自動でアクセスしたいなら(すでに回答がありますが)Sub test1()
 Sub test1()
  Dim myFile As String
  myFile = CreateObject("WScript.Shell"). _
      SpecialFolders("Desktop") & "\読込\a.csv"
  MsgBox myFile
 End Sub

 'ファイル名が a.csv であるのは分っているが、D:ドライブのどのフォルダに
 '入れたか忘れてしまったときは Sub test2()  ◆↑の宣言部を使用

 Sub test2()
  Dim myFile As String
  Dim ok As Long
  Dim ss As String * MAX_PATH_PLUS1

    ok = SearchTreeForFile("D:\", "a.csv", ss)
    If (ok <> 0) Then
        myFile = Left$(ss, InStr(ss, vbNullChar) - 1)
        MsgBox myFile
    End If

 End Sub

 '自前でファイル一覧を見ながら選択するときは Sub test3()

 Sub test3()
  Dim myFile
    myFile = Application.GetOpenFilename("CSV,*.csv")
    If VarType(myFile) = vbBoolean Then Exit Sub

    MsgBox myFile
 End Sub

 等々...
(kanabun) 2014/11/16(日) 11:48

カリーニン 様
kanabun   様

返信回答ありがとうございます。

カリーニン様
ディスクトップとデスクトップとあまり気にしていませんでしたが、
「誤り」と指摘していただきありがとうございます。

カリーニン様、kanabun様の回答をもとに
下記のようなマクロができました、ありがとうございます。

正常に動いているのですが
過去ログ等を参考に作成しており意味が判っていない部分があります。
(1)@下記のコードの Input #1 以下を短く記載できないでしょうか
(2)Akanabun様の回答の冒頭にある、Option Explicit以下のコードは
   知識不足で意味が分からず触っていません。 
   変数の宣言のようですが簡単にご教示願えませんでしょうか
 

Sub CSVファイルを読込む()
Dim D(13) As String '読み取ったデータを格納するための変数
Dim 行 As Integer '貼り付けるセルの行を示すカウンタ
Dim 列 As Integer '   〃    列   〃
Dim myFile As String 'デスクトップの「読込」内「a.csv」

  myFile = CreateObject("WScript.Shell"). _
      SpecialFolders("Desktop") & "\読込\a.csv"
  MsgBox myFile
    Worksheets("Sheet1").Activate           '貼り付け用ワークシートをアクティブにする
        Cells.Clear                         'すべてのセルをすべてクリアする
    Open myFile For Input As #1             'CSVファイルをシーケンシャル入力モードで開く
    Do Until EOF(1)                         'EOFでない間は
        行 = 行 + 1                         '行カウンターに 1 加える
        Input #1, D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8), D(9), D(10), D(11), D(12), D(13)
                                             'CSVファイルを読み取る
        For 列 = 1 To 13                      '列カウンタを1から始めて3以内なら(反復時に1加える)
            Cells(行, 列) = D(列)           '読み取ったデータをセルにセットする
        Next                                'For..Nextする(繰り返す)
    Loop                                    'Doループする(繰り返す)
    Close #1                                'ファイルを閉じる
End Sub

(minoru) 2014/11/16(日) 14:48


 > 最初の列にある文字列を20文字ずつに分けて「b.csv」の1−3列に 転記
 の処理を考えてみました。

 Sub CSVファイル編集()
  Const P = 20 '何文字に分けるか 文字数をココに指定

    'デスクトップに \読込\ フォルダがあれば移動する(なければ Currentディレクトリは移動しない)
    Dim myFile
    Dim myPath As String
    myPath = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\読取\"
    If CreateObject("Scripting.FileSystemObject").FolderExists(myPath) Then
        ChDrive myPath
        ChDir myPath
    End If
    'ファイル選択
    myFile = Application.GetOpenFilename("CSV,*.csv", Title:="CSVファイルを選択")
    If VarType(myFile) = vbBoolean Then Exit Sub
    myPath = Left$(myFile, InStrRev(myFile, "\"))

    Dim io As Integer
    Dim oo As Integer
    'Dim outFile
    Dim outFile As String
    outFile = myPath & "b.csv"
    'outFile = Application.GetSaveAsFilename(outFile, "CSV,*.csv", "保存ファイル")
    'If VarType(outFile) = vbBoolean Then Exit Sub
    outFile = InputBox("出力ファイル名", "ファイル保存", outFile)
    If StrPtr(outFile) = 0& Then Exit Sub

    io = FreeFile()
    Open myFile For Input As io
    oo = FreeFile()
    Open outFile For Output As oo

    Dim ss As String
    Dim v
    Do While Not EOF(io)
        Line Input #io, ss
        v = Split(ss, ",", 2)
        ReDim s(1 To 4) As String
        s(1) = Left$(v(0), P)
        s(2) = Mid$(v(0), P + 1, P)
        s(3) = Mid$(v(0), P + P + 1, P)
        s(4) = v(1)
        Print #oo, Join(s, ",")
    Loop
    Close io, oo
    MsgBox "出力しました", , outFile
 End Sub

(kanabun) 2014/11/16(日) 18:18


 Loopの中をちょっと解説すると
 >    Line Input #io, ss
 >    v = Split(ss, ",", 2)
 >    ReDim s(1 To 4) As String
 >    s(1) = Left$(v(0), P)
 >    s(2) = Mid$(v(0), P + 1, P)
 >    s(3) = Mid$(v(0), P + P + 1, P)
 >    s(4) = v(1)
 >    Print #oo, Join(s, ",")

  (何文字で分割するか 定数P は 簡単のため P = 5 すなわち5文字づつとします)
 >    Line Input #io, ss
       入力ファイルから一行読み込みます。たとえばその一行が
        ss = "ABCDEあいうえおxyz,1,2,3,4,5,6,7,8,9,10,11,12" 
       のような文字列だったとすると、
       ↓カンマで2つの分節に分割すれば
 >    v = Split(ss, ",", 2)
       v(0) には "ABCDEあいうえおxyz" 部分が
       v(1) には "1,2,3,4,5,6,7,8,9,10,11,12" の部分が格納されます。
 >    ReDim s(1 To 4) As String
       分割後の文字列を格納する配列を用意します(初期化します)

 >    s(1) = Left$(v(0), P)         左5文字 よって s(1) = "ABCDE"
 >    s(2) = Mid$(v(0), P + 1, P)   6番目から5文字分 s(2) = "あいうえお"
 >    s(3) = Mid$(v(0), P + P + 1, P) 11番目から 5文字分 s(3) = "xyz"
      s(4) には v(1)全部をコピーします。
 >    s(4) = v(1)

      s(1)〜s(4)をカンマ区切りで連結した文字列を出力します。
 >    Print #oo, Join(s, ",")
      具体的には
      Print #oo, "ABCDE,あいうえお,xyz,1,2,3,4,5,6,7,8,9,10,11,12"
      が出力されます。
(kanabun) 2014/11/17(月) 10:45

kanabun様

お世話になります、
2回も詳細な返信ありがとうございます、今試しましたが正常に入力できました。
少し教えて下さい、
SSを3分割の場合は

 v = Split(ss, ",", 3)
     ReDim s(1 To 5) As String
     s(1) = Left$(v(0), P)
     s(2) = Mid$(v(0), P + 1, P)
     s(3) = Mid$(v(0), P + P + 1, P)
     s(4) = v(1)
     s(5) = v(2)
     Print #oo, Join(s, ",")
上記のコードで正常に終了しましたが、最初の","と次の","で3分割している
v(1) は、"1"
v(2) は、"2,3,4,5,6,7,8,9,10,11,12"が格納される。との理解であっていますか?

a.csvよりエクセルに入力後に、別のシートに転記後にb.csvに転記を想定しており
まして、下記のように転記先のセル位置が連続していない場合の対応についてヒン
トとを提示いただけませんか?
a.csv b.csv
A列 ⇒   CDE列
B列 ⇒   AY列 BB列 ・・・20字であふれた場合はBBを使用
C列 ⇒   VWXYZ列・・・・・20字であふれた場合はWXYZの順で使用
D列 ⇒   FG列・・・・・・・・40字であふれた場合はG列使用
E列 ⇒   H
F列 ⇒   J
G列 ⇒   転記なし
H列 ⇒   O
I列 ⇒   S
J列 ⇒   T
K列 ⇒   U 
L列 ⇒   AG
M列 ⇒   AH

(minoru) 2014/11/18(火) 00:53


 > 上記のコードで正常に終了しましたが、最初の","と次の","で3分割している
 > v(1) は、"1"
 > v(2) は、"2,3,4,5,6,7,8,9,10,11,12"が格納される。との理解であっていますか?
 それでOKです。要するに、2分割なら Split(ss, ",", 2) で 文字列中の最初のカンマ
だけが機能し、
  v(0) = "ABCDEあいうえおxyz" と 
  v(1) = "1,2,3,4,5,6,7,8,9,10,11,12" 
の2つになるけど、Split(ss, ",", 3) と3分割なら 初めのカンマと2つ目のカンマで
分割されるから、おっしゃるように v(0), v(1), v(2) に分割され収まる、ということです。

 > エクセルに入力後に、別のシートに転記後にb.csvに転記を想定しており 
 > まして、下記のように転記先のセル位置が連続していない場合の対応についてヒン 
 > トとを提示いただけませんか?
 Excelシートを使うことは考えていませんでしたので↓、

 >    Line Input #io, ss
 >    v = Split(ss, ",", 2)
 >    ReDim s(1 To 4) As String
 >    s(1) = Left$(v(0), P)
 >    s(2) = Mid$(v(0), P + 1, P)
 >    s(3) = Mid$(v(0), P + P + 1, P)
 >    s(4) = v(1)
 >    Print #oo, Join(s, ",")
 ぼくからのヒントはないのですが、

 >>    Print #oo, Join(s, ",")
 >     具体的には
 >     Print #oo, "ABCDE,あいうえお,xyz,1,2,3,4,5,6,7,8,9,10,11,12"
 出力先がファイルのときはカンマで結合した文字列を一行分まとめてPrintしますが、
 シートのセルに出力なら、Joinする前の配列状態を出力します。

    Dim ss As String
    dim y As Long
    Dim v
    Do While Not EOF(io)
        Line Input #io, ss
        v = Split(ss, ",", 2)
        ReDim s(1 To 4) As String
        s(1) = Left$(v(0), P)
        s(2) = Mid$(v(0), P + 1, P)
        s(3) = Mid$(v(0), P + P + 1)
        s(4) = v(1)
        'Print #oo, Join(s, ",")
        y = y + 1   '行カウンタ
        Cells(y, 1).Resize(, 4).Value = s '一行分 Sheet に吐き出し
    Loop
(kanabun) 2014/11/18(火) 10:17

kanabun様

返信ありがとうございます。
22日と23日に集中して取り組みますので疑問点を質問するかも
しれません。
気が付きましたら、返信を期待しております。
最初の方に教えていただいた、ファイルの選択方法は別のファイル
に組み込み重宝しております。
ありがとうございました。
(minoru) 2014/11/19(水) 00:51


 読み取った一行ss をカンマで Splitすると 
       v = Split(ss, ",")
 vは 0〜12 までの要素の配列になります。
 これを C列を1とする列番号の配列 ReDim s(1 To 52) に入れ直すと

 v(0) ⇒ 1,2,3
 v(1) ⇒ 49, 52
 v(2) ⇒ 20,21,22,23,24
 v(3) ⇒ 4,5
 v(4) ⇒ 6
 v(5) ⇒ 8
 v(6) ⇒ 転記なし
 v(7) ⇒ 13
 v(8) ⇒ 17
 v(9) ⇒ 18
 v(10)⇒ 19
 v(11)⇒ 31
 v(12)⇒ 32

    Dim ss As String
    dim y As Long
    Dim v
    Do While Not EOF(io)
        Line Input #io, ss
        v = Split(ss, ",")
        ReDim s(1 To 52) As String
        s(1) = Left$(v(0), P)
        s(2) = Mid$(v(0), P + 1, P)
        s(3) = Mid$(v(0), P + P + 1)
        s(4) = v(3) を加工
        s(5) = 
        s(6) = v(4)
        s(8) = v(5)
        s(13) = v(7)
        :
        :
        y = y + 1   '行カウンタ
        Cells(y, 3).Resize(, 52).Value = s '一行分 Sheet に吐き出し
    Loop

 ...みたいなことになるんかなぁ
(kanabun) 2014/11/19(水) 07:38

kanabun 様

的確なアドバイスありがとうございます。
下記のコードで正常に動作しました。

度々の質問で申し訳ないのですが
「csv」で出力の時は気がつきませんでしたが「txt」で出力すると
,,,,,,,,,,,
,,,,,,,,,,,
と空白の列が入力されていました。
b.csvは空白行を削除前は273kbでしたが削除すると6kbになりました。

最下行を取得して繰り返す回数を決めるか、""になるまで繰り返すに
しようとしています。
a,csv (ioファイル)の最下行の取得方法をご教示願いませんでしょうか

記載したコード(正常に動いています 感謝しております)
Sub CSVファイル編集()

  Const P = 40  'AとD列を40文字に分割
  Const Q = 20  'BとC列を20文字に分割

    'デスクトップに \読込\ フォルダがあれば移動する(なければ Currentディレクトリは移動しない)
    Dim myFile
    Dim myPath As String
    myPath = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\読込\"
    If CreateObject("Scripting.FileSystemObject").FolderExists(myPath) Then
        ChDrive myPath
        ChDir myPath
    End If

    'ファイル選択
    myFile = Application.GetOpenFilename("CSV,*.csv", Title:="CSVファイルを選択")
    If VarType(myFile) = vbBoolean Then Exit Sub
    myPath = Left$(myFile, InStrRev(myFile, "\"))

    Dim io As Integer
    Dim oo As Integer
    'Dim outFile
    Dim outFile As String
    outFile = myPath & "b.csv"
        'outFile = Application.GetSaveAsFilename(outFile, "CSV,*.csv", "保存ファイル")
        'If VarType(outFile) = vbBoolean Then Exit Sub
    outFile = InputBox("出力ファイル名", "ファイル保存", outFile)
    If StrPtr(outFile) = 0& Then Exit Sub
    io = FreeFile()
    Open myFile For Input As io
    oo = FreeFile()
    Open outFile For Output As oo

    Dim ss As String
    Dim y As Long
    Dim v
        Line Input #io, ss            'a.csvの1行目を読込(ダミー)
    Do While Not EOF(io)
        Line Input #io, ss            'a.csvの2行目から読込
        v = Split(ss, ",")            '読込行を,で分割 Vに格納V(0)からV(12)
        ReDim S(1 To 54) As String
        S(3) = Left$(v(0), P)         'a.csvのA列(v0)を左から40文字S(3):b.csvのC列へ
        S(4) = Mid$(v(0), P + 1, P)
        S(5) = Mid$(v(0), P + P + 1, P)
        S(6) = Left$(v(3), P)        'a.csvのD列(V3)を左から40文字s(6) b.csvのF列へ
        S(7) = Mid$(v(3), P + 1, P)  'a.csvのD列(V3)の42文字目から40文字をs(7) b.csvのG列へ
        S(8) = v(4)
        S(10) = v(5)
        S(15) = v(7)
        S(19) = v(8)
        S(21) = v(10)
        S(22) = Left$(v(2), Q) 'a.csvのC列(V2)を左から20文字b.csvのV列からZ列へ
        S(23) = Mid$(v(2), Q + 1, Q)
        S(24) = Mid$(v(2), Q + Q + 1, Q)
        S(25) = Mid$(v(2), Q + Q + Q + 1, Q)
        S(26) = Mid$(v(2), Q + Q + Q + Q + 1, Q)
        S(33) = v(12)
        S(34) = v(11)
        S(51) = Left$(v(1), Q)        'a.csvのB列を左から20文字S(51):b.csvのAY列へ
        S(54) = Mid$(v(1), Q + 1, Q)  'a.csvのB列の21字目から20文字をS(54):b.csvのBB列へ
        y = y + 1                     '行カウンタ
        Print #oo, Join(S, ",")  'カンマ区切りを連結した文字列を出力 ダミーで見出行を回避

        'Cells(y, 1).Resize(, 54).Value = s    ' 使用していない マクロを登録したシートへ一行分抽出時に使用
    Loop
    Close io, oo
    MsgBox "出力しました", , outFile
 End Sub

(minoru) 2014/11/23(日) 23:44


 > 「csv」で出力の時は気がつきませんでしたが「txt」で出力すると 
 > ,,,,,,,,,,, 
 > ,,,,,,,,,,, 
 > と空白の列が入力されていました。

 列ですか? 行じゃなくて?

 > 最下行を取得して繰り返す回数を決めるか、""になるまで繰り返すに 
 > しようとしています。 
 > a,csv (ioファイル)の最下行の取得方法をご教示願いませんでしょうか 

 ↑この情報から推定するに、もともとの a.csv のお尻のほうに
 > ,,,,,,,,,,, 
 > ,,,,,,,,,,, 
 という行が 何行か くっついていた、ということのように読めるんですけど?
 .
(kanabun) 2014/11/24(月) 08:57

ご指摘どおりでした、
元のデータに,,,,,,,,が最終行まで入っていました。
よく確認してから質問致します。(反省)

別のファイルで同様なことをしておりますので、
また不明点は別スレにて質問致するかもしれません。

今回は最初の質問から波及して、配列をご教示いただき幅が広がりました。
今までは全部のデータをエクセルシートに貼付してから、関数等で
抽出や削除をしておりましたが、必要な列だけを最初から抽出でき、
無駄な作業が無くなりました。 
大変お世話になりありがとうございました。

(minoru) 2014/11/24(月) 15:14


コメント返信:

[ 一覧(最新更新順) ]


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