[[20181228220926]] 『絶対パスではなく相対パスを取得する。』(アイス) ページの最後に飛ぶ

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

 

『絶対パスではなく相対パスを取得する。』(アイス)

vbaでの相対パスの取得方法についてお尋ねしたいです。

 Private Sub CommandButton1_Click() 
  Dim Dialog_Title As String 
  Dim FilePath As Variant 

  Dialog_Title = "イラストのファイルを選択して下さい。" 

  FilePath = Application.GetOpenFilename(, , Dialog_Title) 

     If FilePath = flse Then 'パスが選択されないとキャンセル 
        Exit Sub 

     Else: TextBox1.Value = FilePath 'テキストボックスにパスを表示 

     End If 

  End Sub 

このようなコードを作りました。ユーザーフォームにコマンドボタンを一つ、テキストボックスを一つ置いています。コマンドボタンを押せばファイルを選択できるようにしていて、パスの取得をしたいファイルをクリックすれば絶対パスが取得できます。しかし、今操作しているPC以外で扱うことになればファイルを参照できません。そこで絶対パスではなく、ファイルをクリックするだけで相対パスを取得できるマクロに変えたいと思いました。いろいろネットや本で調べてはみたのですが、解決できるものがありませんでした。

ちなみに、テキストボックスへ相対パスを一旦表示した後に、2つ目のコマンドボタンを押せば、シートへ入力されるようにしています。
また、参照するファイルはすべてjpgファイルにしています。後から私以外が画像を登録するようにしているため、相対パスにしたいと思いました。
フォルダ内に、ブックと画像を入れているフォルダが1つずつあるという構成です。

どうしても絶対パスしか参照できないので、皆様にお伺いしたいです。よろしくお願いします。

もし相対パスを直接参照できなければ、絶対パスを強引に相対パスに変えるという方法でも大丈夫です。

< 使用 Excel:Excel2016、使用 OS:Windows10 >


>フォルダ内に、ブックと画像を入れているフォルダが1つずつあるという構成です。

Thisworkbook.Path を使いたいという意味でしょうか?

>今操作しているPC以外で扱うことになればファイルを参照できません。

具体的にどんな方法で参照しようとしているのでしょうか。

(マナ) 2018/12/28(金) 22:42


マナさんが確認されていることとかぶりますけど、”何”からの相対になるんですか?
絶対パスを相対にかえたときにどうなるのか例示を示すことは可能でしょうか?

(もこな2) 2018/12/28(金) 22:51


とりあえず

フォルダ名\画像名.jpg

だけを、セルに書き込んでおいて、

Cell関数で自ブックのフォルダは求められるので
別セルで結合してはどうでしょうか。
http://proengineer.internous.co.jp/content/columnfeature/7378#section202

(マナ) 2018/12/28(金) 23:03


>Thisworkbook.Path を使いたいという意味でしょうか?
おっしゃる通りです。自分なりにはやってみたのですが、絶対パスが結局表示されてしまいました。
>私以外の人間が、今開発をしているPCとは別のものを用いて、画像ファイルを表示したり、あるいは画像ファイルを追加したりすることができるようにしたいです。参照方法ですが、ユーザーフォームのイメージを用いています。画像ファイルの相対パスを登録するのも、ユーザーフォームを用いています。コマンドボタンをクリックすれば(GetOpenFilenameなどを用いて)相対パスを取得したいファイルを選べるようになり、そのファイルを開けば(クリックすれば)相対パスをテキストボックスに表示できるというものです。テキストボックスへ一旦表示した後、別のコマンドボタンを押せばパスの登録が完了するといった流れでしょうか。

>マナさんが確認されていることとかぶりますけど、”何”からの相対になるんですか?
ブックを基準として相対パスを取得したいとおもっております。

>絶対パスを相対にかえたときにどうなるのか例示を示すことは可能でしょうか?
現時点での絶対パスは、
C:\Users\〇〇〇(ユーザー名)\Desktop\ブックのあるフォルダ名\画像のあるフォルダ名\ファイル名.jpg
このようなものを取得できるようにはしています。相対に変えるというのは、どうすれば良いのでしょうか。
Thisworkbook.Path & "ファイル名"
でしょうか?これをベタ打ちでシートに登録して、画像を呼び出そうとしたところ、「パスが不正です」というエラーが表示されました。どこを変えれば正常に動作するのかがわからないので困っているところです。

>フォルダ名\画像名.jpg だけを、セルに書き込んでおいて、Cell関数で自ブックのフォルダは求められるので 別セルで結合してはどうでしょうか。
私だけが画像ファイルの追加をするのであればよいのですが、他の人も扱うため、なるべく負荷の少ない(今考えている方法は参照ボタンをクリックし、該当のファイルをクリックするだけでパスを取得できるというものです)方法をとりたいと思っています。CAllで呼び出して結合させるのは良いアイディアのように思います。フォルダ名\画像名.jpg のみをベタ打ちではなく、マクロで取得するにはどうしたらよいでしょうか?

(アイス) 2018/12/28(金) 23:55


>他の人も扱うため、

他の人がする操作を具体的に教えてください。

マクロを使うのであれば、Thisworkbook.Pathでよいし、
マクロを使わないのであれば、CELL関数を使えばよいです。

(マナ) 2018/12/29(土) 00:10


 何でこんな時間にぶつかる。

 >Thisworkbook.Path & "ファイル名" 
 >でしょうか?これをベタ打ちでシートに登録して、画像を呼び出そうとしたところ、
 >「パスが不正です」というエラーが表示されました。どこを変えれば正常に動作するのかがわからないので困っているところです。 

 んなもん自分で確認すればいい。
 たぶん自分で考えることなく、コピペ専門だからだと思います。

 msgbox Thisworkbook.Path & "ファイル名"
(BJ) 2018/12/29(土) 00:14

>他の人がする操作を具体的に教えてください。
他人が扱う操作ですが、
1.マクロを使わない人で画像を参照するだけの人と、
2.同じく基本的にはマクロを使いませんが(用意されたユーザーフォームは使いますが)ユーザーフォームを用いて画像の登録もする人の2パターンにだいたい分かれます。
先ほどは、Call関数だと勘違いしていました。Cell関数ですか。

BJさんコメントありがとうございます。VBAの基礎から勉強してきたわけではないので、デバッグや確認の方法などがどうすればいいか分からない、思いつかない時が正直な所多々あります。時間に追われて結果コピペしてしまっている部分もあります。ですが、本などで調べて解決できる部分は自分なりに理解もして解決している時ももちろんあります。まあそう捉えられてしまっていては意味が無いかもしれませんが。
(アイス) 2018/12/29(土) 00:21


>他の人がする操作を具体的に教えてください。

マクロで、セルに画像の「相対パス」を書き込んだあと、
他のPCで、他の人がどんな操作をするのかを質問しています。

>画像を参照する

とは、具体的にどんな操作でしょうか

(マナ) 2018/12/29(土) 00:25


ハイパーリンクにしておけばよいだけしょうか?

(マナ) 2018/12/29(土) 00:43


私のハイパーリンクの認識が間違っていなければ、ハイパーリンクではありません。
ハイパーリンクは文字列をクリックすると、そのファイルを開けるといったものですよね?

私はパスを基に、ユーザーフォームのイメージへ画像を表示するものにしています。
(アイス) 2018/12/29(土) 00:56


 下記ソースを試してみてください。

 'UserFormモジュール 
 Private Declare PtrSafe Function PathRelativePathToW& Lib "Shlwapi" _
     (ByVal pszPath As LongPtr, _
      ByVal pszFrom As LongPtr, _
      ByVal dwAttrFrom As Long, _
      ByVal pszTo As LongPtr, _
      ByVal dwAttrTo As Long)

 Private Sub CommandButton1_Click()
     Dim Dialog_Title As String
     Dim FilePath As Variant
     Dim ThisPath As String
     Dim buf As String, flg As Long

     Dialog_Title = "イラストのファイルを選択して下さい。"

     FilePath = Application.GetOpenFilename(, , Dialog_Title)
     'パスが選択されないとキャンセル
     If VarType(FilePath) = vbBoolean Then Exit Sub

     ThisPath = ThisWorkbook.FullName
     buf = String$(256, 0)
     flg = PathRelativePathToW(StrPtr(buf), StrPtr(ThisPath), 0, StrPtr(FilePath), 0)
     If flg = 0 Then Exit Sub

     buf = VBA.Left$(buf, InStr(buf, vbNullChar) - 1)
     TextBox1.Value = buf 'テキストボックスに相対パスを表示

 End Sub
( Abyss) 2018/12/29(土) 01:20

 自分で試しもしない、コピペ専門だから、頭が凝り固まってます。
 あなたの言う、絶対パスと相対パスって何ですか?
 具体的に教えてください。
(BJ) 2018/12/29(土) 01:33

 MsgBox Dir(ThisWorkbook.Path & "\..\ftest_img\*.*")

                                   ~~~~~~~~~~~
                                       ↑
                                    画像の有るフォルダ名

(隠居じーさん) 2018/12/29(土) 05:57


 (隠居じーさん) 2018/12/29(土) 05:57 は
 >>フォルダ内に、ブックと画像を入れているフォルダが1つずつあるという構成です。

               | - BOOKフォルダ
 あるフォルダ -|
               | - 画像フォルダ

 BOOKの有るフォルダの一つ上の階層に画像フォルダが在る場合です。
 BOOKの有るフォルダと同じフォルダに有るフォルダ(サブフォルダ)が画像フォルダの場合は

 BOOKフォルダ - 画像フォルダ

 MsgBox Dir(ThisWorkbook.Path & "\ftest_img\*.*")
 です。
(隠居じーさん) 2018/12/29(土) 07:02

>他人が扱う操作ですが、
>1.マクロを使わない人で画像を参照するだけの人と、

>私はパスを基に、ユーザーフォームのイメージへ画像を表示するものにしています。

矛盾していませんか?
ユーザーフォームということは、マクロ利用ではないのですか。

ユーザーフォームのイメージへ画像を表示する部分のマクロを提示できませんか。
その行に、Thisworkbook.Pathを使用するだけのような気がします。

(マナ) 2018/12/29(土) 09:14


マルチポストでしたか。
同時にたくさんの回答者を相手にするのも大変でしょうから
わたしは、こここまでにします。

(マナ) 2018/12/29(土) 09:39


皆様ありがとうございます。

Abyss様のコードを用いれば、相対パスをテキストボックスに取得させることには成功しました。

しかし、私はとんでもない思い違いをしていたかもしれません。

>矛盾していませんか?
>ユーザーフォームということは、マクロ利用ではないのですか。
マクロは確かに使いますかね・・・。画像を見るだけの人と、画像の追加もできる人がいるということです。

>ユーザーフォームのイメージへ画像を表示する部分のマクロを提示できませんか。
UserForm1.Image1.Picture = LoadPicture(Worksheets("Sheet1").Cells(2, 4).Value)
上のようなLoadPicturefメソッドを利用していました。上はシート1のD2セルにあるパスから画像を表示するコードです。

LoadPictureでは相対パスから画像の表示をすることはできなかったのですかね。D2のセルの値を絶対パスにしていれば、画像は表示できましたが、相対パスを入れて画像を表示しようとユーザーフォームを操作したところ、「パスが見つかりません」というエラーメッセージが表示されてしまいました。

この画像の表示方法(LoadPcture)は変更せずに、他のPCで操作した時であってもフォルダやファイルの場所を決めていれば画像が表示されるようにしたいです。
一旦相対パスを記述しておいて、画像を表示するマクロの直前で相対パスを絶対パスに強引に変更するという方法しかないでしょうか?
(アイス) 2018/12/29(土) 10:01


 試してないけど。

 ThisWorkbook.Path & "\..\画像固定フォルダ\AAAA.jpg"
(BJ) 2018/12/29(土) 10:50

画像を表示する直前に、画像の入ったフォルダ名以降のみをMID関数を用いて取り出し、あとはThisWorkbbok.Path & MID関数で絶対パスを毎回表示させるようにしました。

Dim txt As String

 txt = ws1.Range("B" & i).Value 
 ws1.Range("B" & i).Value = ThisWorkbook.Path & Mid(txt, InStr(txt, "\画像のあるフォルダ名") - 1) 

これで、解決できました。ちなみに、コマンドボタンをクリックした時に上のコードを実施し、そのあと続けてユーザーフォームを表示(画像の表示)をしています。変数のiは最終行までを指していて、for i 構文でループさせています。

相対パスで直接画像を表示できればいいのですが、どうもうまくいかないので、このようにしました。
シート1のB列を毎回書き換えるのでデータが増えれば増えるほど重くはなってしまいますが、1万を超えるようなデータではなく多くても千くらいのパスしか記入しないと思いましたので、このように致しました。

ご教授して頂いた皆様、本当にありがとうございました。
(アイス) 2018/12/29(土) 15:48


カレントフォルダをきちんと設定すれば
相対パスで取得できます。
mougでそういう回答がされていますけど?
(γ) 2018/12/29(土) 16:08

 >画像を表示するマクロの直前で相対パスを絶対パスに強引に変更するという方法しかないでしょうか?

 なんで、それが強引なんですかねぇ・・
 普通にやっている事だと思うんですけども。 

 今回は、どこにあるか決まっているので、相対パスを動的に判断する必要もない。
       ↓
 >フォルダ内に、ブックと画像を入れているフォルダが1つずつあるという構成です。 

 つまり相対パスすら必要なく、ファイル名だけで十分のハズ。
 (それで、各PCのThisWrokbookのPathから、絶対パスは作れる。)

 >シート1のB列を毎回書き換えるのでデータが増えれば増えるほど重くはなってしまいますが、

 何故、B列のデータをいちいち書き換えに行く必要があるのかも、私には不可解。

(半平太) 2018/12/29(土) 16:18


>相対パスで直接画像を表示できればいいのですが、どうもうまくいかないので、
どのようなコードを実行した結果、できないと判断したのですか?
後学のために教えていただきたい。
(γ) 2018/12/29(土) 18:28

OS(Windows)のファイルシステムで相対パスを使う場合に、
何を基準とするかを指定するのが、OSの「カレントフォルダ」という機構です。
このことの理解がなければ、相対パスを理解したことになりません。
その「カレントフォルダ」を Excelサイドから
・確認したり(CurDir関数)、
・変更したりする(ChDirステートメント)
ことができます。
 
こうしたことが提案され、コードも提示されているのにろくすっぽ確認せず、
>基準フォルダ = ThisWorkbook.Path
>この回答を拝読してこの方法があったかとおもいました。
などと頓珍漢なコメントでお茶を濁しているのはとても残念なことでした。
  
マルチポストして、どちらも中途半端なことになっていることも悲しいです。
もう少しまともにネット上にある資源を使うことをお薦めします。

(γ) 2018/12/30(日) 10:07


皆さまご指摘等ありがとうございます。

ただ今PCが手元にありませんので後ほどまた更新させていただきます。調べる時間に余裕がなく、かれんとフォルダ等についても十分に調べられていない現状でございます。

失礼致します。また後ほどよろしくお願いします。
(アイス) 2018/12/30(日) 21:15


>マナさんが確認されていることとかぶりますけど、”何”からの相対になるんですか?
ブックを基準として相対パスを取得したいとおもっております

まぁ、答えは出てるっぽいけど、ブック【が保存されているフォルダ】を基準としたパスに置換したいってことですよね。

そのブックが一度保存されたことがあるのが条件ですけど、皆さんが提示されているように
↓ブックが保存されているフォルダ
(Workbookオブジェクト).Path

↓ブックのフルパス
(Workbookオブジェクト).FullName

で取得できます。したがって
>絶対パスを相対にかえたときにどうなるのか例示を示すことは可能でしょうか?

現時点での絶対パスは、 C:\Users\〇〇〇(ユーザー名)\Desktop\ブックのあるフォルダ名\画像のあるフォルダ名\ファイル名.jpg

ということであれば、
パスを取得する側では↓これを置換して削っておき、「どこかに覚えておいて」

 C:\Users\〇〇〇(ユーザー名)\Desktop\ブックのあるフォルダ名 

画像を表示する側では、「どこかに覚えておいた」↓これを組み合わせるようにすればよいですね。

 Thisworkbook.Path & "\画像のあるフォルダ名\ファイル名.jpg"

ちなみに、ブックが保存されているフォルダの配下(下位)であれば、上記のようにただの文字列操作でよいでしょうけど、親フォルダやさらにその親フォルダとかであれば、OREO名義?のほうで回答があったsplit関数を使って一度分解するとか、FileSystemObjectなどをつかってFolderオブジェクトとして取得するどの工夫が必要になるようにおもいます。
【参考:FileSystemObject】
http://www.atmarkit.co.jp/ait/articles/1705/01/news019.html

もっとも、デスクトップなどの特殊フォルダの配下ということであれば、自ブックが保存されているフォルダからの相対に拘らずとも良いようにもおもいますが・・
【参考:特殊フォルダの取得】
http://officetanaka.net/excel/vba/tips/tips107.htm

(もこな2) 2018/12/31(月) 13:46


 だから、(隠居じーさん) 2018/12/29(土) 07:02
 と、かぶっちゃったけど、画像が保存されているフォルダ名は固定なんでしょ。

 MsgBox Dir(ThisWorkbook.Path & "\..\画像が保存されているフォルダ名\*.jpg")
 とか、
 画像ファイル名が直接指定なら
 ThisWorkbook.Path & "\..\画像固定フォルダ\AAAA.jpg"

(BJ) 2018/12/31(月) 14:07


 >フォルダ内に、ブックと画像を入れているフォルダが1つずつあるという構成です。 

 >>絶対パスを相対にかえたときにどうなるのか例示を示すことは可能でしょうか? 
 >現時点での絶対パスは、 
 >C:\Users\〇〇〇(ユーザー名)\Desktop\ブックのあるフォルダ名\画像のあるフォルダ名\ファイル名.jpg 

 上の二つは矛盾してないですか?

 上なら C:\Users\〇〇〇(ユーザー名)\Desktop─┬─ 画像のあるフォルダ名  \ファイル名.jpg 
                          └─ ブックのあるフォルダ名\ブック.xlsm

 下なら C:\Users\〇〇〇(ユーザー名)\Desktop\ブックのあるフォルダ名─┬─ 画像のあるフォルダ名\ファイル名.jpg
                                                 └─ ブック.xlsm

 とっちにしても、Abyssさんのコードを使えば、相対パスが動的にText1に格納できる。

 その後、その相対パスをワークシートに転記する。

 画像を呼び出す時は、BJさんのアドバイスに従って・・

     txt = ws1.Range("B" & i).Value
     UserForm1.Image1.Picture = LoadPicture(ThisWorkbook.Path & "\" & txt)

 とすれば、絶対パスはシートに書かないで済みます。

(半平太) 2018/12/31(月) 22:51


随分と更新が遅くなってしまいました。申し訳ございません。

まず、LoadPictureの部分ですが、

UserForm2.Image1.Picture = LoadPicture(vw(2))

このように配列を用いています。

vw = Split(cDimQ(iCount), "|")

        UserForm2.Label2.Caption = iCount + 1 & " / " & qNum & "問" '何問目かを表示
        UserForm2.CommandButton1.Caption = vw(0)
        UserForm2.CommandButton2.Caption = vw(1)
        UserForm2.Image1.Picture = LoadPicture(vw(2))

問題をスタートさせるための準備としてのコードの一部が以下です

    Dim i As Long
    Dim iC As Long
    Dim iw As Long
    Dim cw As String
    Dim vw As Variant

 iMax = ws6.Cells(ws6.Rows.Count, "A").End(xlUp).Row

    Randomize

    With ws6
        For i = 2 To iMax
            If UserForm1.ComboBox1.Text = .Cells(i, "A").Text Or UserForm1.ComboBox1.Text = "すべて!" Then

                ReDim Preserve cDimQ(iC)
                cDimQ(iC) = .Cells(i, "B").Text & "|" & .Cells(i, "C").Text & "|" & .Cells(i, "D").Text
                iC = iC + 1

            End If

        Next i
    End With

    For i = 1 To UBound(cDimQ)
        iw = WorksheetFunction.RandBetween(0, iC - 1)
        cw = cDimQ(iw)
        cDimQ(iw) = cDimQ(i)
        cDimQ(i) = cw
    Next i

    ReDim cDimA(UBound(cDimQ))
    For i = 0 To UBound(cDimQ)
        vw = Split(cDimQ(i), "|")
        cDimA(i) = vw(0)
        If Rnd() * 2 < 1 Then
            cDimQ(i) = vw(1) & "|" & vw(0) & "|" & vw(2)
        End If
    Next i

この状態において、LoadPicture(ThisWorkbook.Path & vw(2))と変更し、シートに記述していたパスも絶対パスから画像ファイル名だけの相対パスを記述しておきましたが、パスが不正ですとエラーが出ました。

現状ではいちいち絶対パスにし直していますが、LoadPicture(ThisWorkbook.Path & "\" & txt)だと、確かに相対パスだけでいいので経済的だと思います。しかし、うまくできませんでした・・・。すみません、配列のコードがどうなっているのかをまだ100%理解できていないまま使っているので今はここまでしか申し上げられそうにありません・・・。
あと、いままではThisWorkbook.Path & ・・・をLoadPictreで用いるのではなく、シートに記述するものだと思っていました。LoadPictureのコードでThisWorkbook.Pathを用いても大丈夫なのですね。

ブックやフォルダはこのような構成でしょうか。フォルダ内にブックとイラストフォルダがあり、さらにイラストフォルダの中にイラストがいくつも入っているという状態です。

 C:\Users\〇〇〇(ユーザー名)\Desktop\ブックのあるフォルダ名─┬─ 画像のあるフォルダ―――\ファイル名.jpg
                                         └─ ブック.xlsm

ChDirステートメントについては先週に調べてみましたが、読んだ時には理解できていなかったので今度調べます。split関数もあまり理解できていないですね。専門用語ばかりでなかなか理解が進まないですがどうにか理解できるよう努力します。

今別の問題にあたって1週間ほど経過しているのでそれがどうにかなってからでしょうか・・・。

今記述しているコードでは不明瞭で伝わらないかもしれません。いかんせん自分でも理解できていないもので。何が必要であるか分かればおっしゃっていただければと思います。不明瞭すぎて何も分からない場合はもう少々お時間を頂きたいです。よろしくお願いします。

ちなみに今困っている別件のことをさらに聞くのはやはりマナーとしてよくないですかね?
(アイス) 2019/01/08(火) 00:42


追記と謝罪です。

もう一度コーディングしてみたところ、ThisWorkbook.Path & vw(2) で正しく画像を読み込めました。申し訳ございません。

私の至らなさで多くの方々を振り回してしまって申し訳ないです。
(アイス) 2019/01/08(火) 00:54


 >現状ではいちいち絶対パスにし直していますが、LoadPicture(ThisWorkbook.Path & "\" & txt)だと、確かに相対パスだけでいいので経済的だと思います。

 おっしゃる意味がわかりません。

 その指定は絶対パス指定じゃありませんか。どこが相対パスなんですか?
 だってThisWorkbook.Pathは "C:\Users\〇〇〇(ユーザー名)\Desktop\ブックのあるフォルダ名"でしょ?
 ThisWorkbook.Path & "\" & txt という指定は、C:\からはじまっているわけだから、絶対パスですよ。
 絶対パス、相対パスの意味が通じていないような気がします。

 私はLoadPictureを使用する際に、相対パスを使うべきだとも思っていませんが、
 「LoadPictureでは相対パスは使えない」と主張されるので、それは事実ではないと申し上げています。
 ・ThisWorkbook.Pathがカレントフォルダになっている前提で、
 ・そこを基準とした相対パス である、"画像のあるフォルダ\ファイル名.jpg" を指定すれば、
  つまり、LoadPicture(画像のあるフォルダ\ファイル名.jpg)とすれば、
 画像の読み出しはできるはずです。
 以上です。

(γ) 2019/01/08(火) 07:43


スマホから書きます。
シートには相対パスが書かれているのでこれが相対パスで呼び出すものと思いましたが、これも絶対パスということになるのですね。
カレントフォルダにしておいて、LoadPicture(画像のあるフォルダ\ファイル名.jpg)ですか、もしかしたら私のカレントフォルダの解釈が間違っているかもしれないので、後ほど調べて、コーディングもしてまたご報告させていただきます。
ありがとうございます。
(アイス) 2019/01/08(火) 15:16

>シートには相対パスが書かれているのでこれが相対パスで呼び出すものと思いましたが、これも絶対パスということになるのですね。

txtというのが相対パスとすれば,
ThisWorkbook.Path & "\" & txtとした段階でそれは絶対パスです。
相対パスで呼び出したとは言わないと思います。
絶対パスに変換したうえで絶対パスで呼び出す、と言うと思います。

それとは別に、
>ThisWorkbook.Path & vw(2) で正しく画像を読み込めました。
というのが逆に理解に苦しみます。
vw(2)は画像のファイル名だけですよね。
すると"画像のあるフォルダ"という情報がどこにも指定されていない絶対パスなので、
正しく読み込めるはずがありません。

いずれにしても、別の要件があるのでしたら、そちらに集中して下さい。
私が申し上げたいことは前期のもので尽きていますので、、
ここまでとさせて頂きます。

(γ) 2019/01/09(水) 00:04


 まあ、この人は無理だと思いますよ。
 自分の凝り固まった自分に都合の良い認識だけで、人の説明を聞くことなく暴走しているだけだから・・・。
 ある意味、コルムさんに似てる。
 同じような方なのかな?
(BJ) 2019/01/09(水) 01:01

γ様、ありがとうございます。2月になればある程度勉強する時間もできるのでもっと勉強しますね。

ThisWorkbook.Path & vw(2) のvw(2)にはイラスト集のフォルダ名からのパスが記載されたセルを参照しています。つまり、フォルダ名まで入っています。
  \イラストフォルダ名\イラストファイル名  です。伝え方が悪かったようで申し訳ございません。

BJ様コメント拝読しました。私に何を仰ろうと構いません。直接非難、批判なさっているわけですし、私にも非はあると思いますので。しかし、間接的であろうとも他人の誹謗中傷のようなことを、しかもその本人がいないところでするのは如何なものかと思います。私は掲示板のルールやマナーについては詳しくないです。その方が何をしたかも知りません。けれども、一般的に考えてここでわざわざ言及するべきではないと思います。
(アイス) 2019/01/09(水) 12:04


 何かと反論しないと気が済まない教職員。
 なぜかこの手の方が多い。
(BJ) 2019/01/09(水) 15:28

私は教育について修めてはいますが、教職員ではありません。

>何かと反論しないと気が済まない教職員。
>なぜかこの手の方が多い。
BJ様がどういった経験をされたか存じ上げませんが、偏見ではないでしょうか?さんざんマナーがどうだと話していた方が結局非も認めずに、さらに私(私ではなく教職員ですかね)を貶す意味が分かりません。それに私を直接非難するのではなく、対象を広げて非難する意味も分かりません。そもそもなぜ教職員だと断定するのでしょうか。教職員は昼間にこのような書き込みは普通できません。
結局はあなたも同じマナー違反をしているのではないでしょうか?偏見を持つのは勝手ですが、ここで振りまくのはやめていただきたいです。それと、別に私は自分の至らなさを棚に上げているわけではございませんので。

この掲示板でこれ以上この議論しても無意味なのでこれで最後とさせて頂きます。これに対してコメントしなくても結構です(して頂いてももちろん構いませんが)。

質問内容と関係の全く無い書き込みを続けたことにお詫び申し上げます。それでは失礼致します。
(アイス) 2019/01/09(水) 16:31


横からですが、なんか荒れるチックな感じになっちゃってますね・・・
たぶんそれぞれの思い描く?"相対パス"が違うのですれ違っちゃてるんじゃないですかね。

アイスさんが知りたいのは、「ブックが保存されているフォルダ」を起点にしたパスのこと。
回答者の皆さんが答えているのは「カレントフォルダ」を起点にしたパスのこと。

この二つって同じようで違うんですよね。
このことについてネット検索してみたら、わかりやすそうなサイトがあったので紹介しておきます。
(もうごらんになってるかもですが)
http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_140.html
http://shuhho.hatenablog.com/entry/excelvba-25

(もこな2) 2019/01/09(水) 18:56


 >回答者の皆さんが答えているのは「カレントフォルダ」を起点にしたパスのこと。 

 もこな2さん

 「皆さん」はちょっと広げすぎでは?

 カレントフォルダは、状況依存(※)の危ない基準と認識していますので、その起点は私の頭にないです。

 (※)シートをアクティブにして、親シートの修飾を省略するコーディングに似ているなぁと感じます。

 Abyssさんも ThisWorkBook基準で相対パスを求めています。
          ↓
 >ThisPath = ThisWorkbook.FullName

 あと、こういうのは全体として、絶対パスと言うんでしょうか? それとも相対パス?
             ↓
> ThisWorkbook.Path & "\..\画像固定フォルダ\AAAA.jpg"

 特に、お返事は必要ありません。 m(__)m 念のため

( 半平太) 2019/01/09(水) 20:30


いや私も、
>私はLoadPictureを使用する際に、相対パスを使うべきだとも思っていませんが、
>「LoadPictureでは相対パスは使えない」と主張されるので、それは事実ではないと申し上げています。
そこだけが主眼です。

(γ) 2019/01/09(水) 20:40


>「皆さん」はちょっと広げすぎでは?
言われてみればそうかも・・・すみません。

言いたかったのは「何に」対する「相対」なのか質問者と回答者で前提が違っているように思えるので
そこから合わせていかないと話がかみ合わないですよねってことでした。

しかし、あらためて「相対パス」とは何ですかと聞かれると、どういえばいいんでしょうね
カレントフォルダからみたパスって言っていいものなのか自分にはちょっと分からないです。

コマンドプロンプトだったら、左に表示されてるフォルダから見たものとか言えばいいんでしょうけど、ExcelVBAだと、自ブックの親フォルダとマクロ実行時のカレントフォルダが必ずしも一致するとは限らないので、いざ説明しようとすると難しい・・・

(もこな2) 2019/01/10(木) 00:04


 >あと、こういうのは全体として、絶対パスと言うんでしょうか? それとも相対パス?
 >ThisWorkbook.Path & "\..\画像固定フォルダ\AAAA.jpg"

 相対パスとは、一言も言ってないです。
 これは、最初に言ってた総元のフォルダをいちいちパス文字を分解することなく見る方法です。
 隠居じーさんさんも説明されてます。
 私は、DOS使ってた人からの伝授で呼び名は知らない。
 もっとも、相対パスって何ですか?と聞いても、質問者本人が何も答えないので、相対絶対パス論は無視しました。
 ころころ、フォルダ関係が変わっているし。

 総元フォルダ――――――ブックの入っているフォルダ―――ブック1
        |
         ―――――画像の入っているフォルダ――――画像

 ブック1から見たブックの入っているフォルダの上の総元フォルダに入っている画像フォルダの中の画像ファイル。
 ブックの入っているフォルダと画像の入っているフォルダが入ってる元フォルダが移動されても、そのまま使える便利な書き方。
 使い方がいまいちよく解ってない、infなんかでの _xxxxx.inf に似てる??

(BJ) 2019/01/10(木) 01:35


 主語が相対的だから難しい気がします
 プログラム単位でみたら、Thisworkbook.Pathを使った時点で、相対パスじゃないんですか?
 ファイル名も変わりますし。

 メソッド等の単位で見れば、Thisworkbook.Pathを使おうが、手打ちであろうが
 フルパスであれば絶対パスでいいような

 γさんが言いたいのは、フルパスと相対パス的表記(./image/x.jpg)のどちらでも開けますよ
 ってことですよね?

 んで、アイスさんがセルに打ち込んである文字は、相対パスですらなく、ルートパスだから、
 結果として読み込めないでいいんじゃないですか?
(稲葉) 2019/01/10(木) 06:13

相対パスとしては
./フォルダ名/ファイル名.jpg
と思っていました。

答えになっているでしょうか?

Image1.Picture = LoadPicture("相対パス")
で読み込もうとしたところ、ダメでした。保存場所は、本来のブックと同じ場所に保存していて、1つ下の階層(ブックと同じページ階層(?)にあるイラストフォルダ内)にイラストファイルは入れてあります。
しかし、この状態でカレントフォルダを設定しておけばロードできるということですね。
カレントフォルダを設定するというのは、Cドライブからブックのあるフォルダまでを設定し直すということですよね?別のPCを使えばこれは使えなくなるのでしょうか?

ルートパスというのもあるのですね・・・。

あと、相対パスの時は \ を使わずに / を用いるので合ってますかね?

(アイス) 2019/01/10(木) 13:21


どうやら、相対パスというものを誤解されているようですね。 そして、どういう認識なのか確認しようとする回答者さん達の意図を理解せず、自分の考えに固執して、雰囲気が悪くなったように思います。

相対パスとは、どこかを基準として「相対」して指定するものの事です。 具体的には、「.\」(カレントの階層)とか「..\」(カレントの1つ上の階層)を使ったパス指定ですね。 また、\ はWindowsのパスの区切り文字であり、/ はLinuxやWebのパスの区切り文字でしかありません。 「/」を使って書いたものが相対パスだ、というのは間違いだし、相対パスには「\」を使わない、というのも間違いです。

 > ./フォルダ名/ファイル名.jpg
これは確かに相対パス指定です。「/」を使っているからではなく、先頭が「.」だからです。 
でも、Excel VBAは「/」をパス区切りと解釈しないし、カレントがどこかは不確実なので、相対パス指定はすべきではありません。
(Windowsアプリでは相対パスを使うべきではないので、ChDirとかCurDir関数を覚える必要はないでしょう)

結局、成功したのは「\フォルダ名\ファイル名.jpg」と書いていたときですよね? これは、相対パス指定ではなく、絶対パスの一部になります。 「.\」とか「..\」を使っていませんから。 Thisworkbook.Path & vw(2) とする事によって、ブックのある絶対パスに追加のフォルダとファイル名を連結して、ファイルのフルパスを作った、という意味であり、どこにも相対する要素なんて無かった事になります。
(???) 2019/01/10(木) 13:51


 ごめんなさいね、混乱させるようなこと言って
 ???さんからご指摘有りましたが、通常以下に説明するような使い方はしません。
 γさんの「LoadPicture〜〜〜」の部分を理解していただければと思います。

 分かりやすいようにちょっと以下のこと試してみてください。
 1)下図のように、どこでもいいのでフォルダを3つ作ってください。
 2)親フォルダの中に、123.jpg
   子フォルダの中に、456.jpg
            このブック
   孫フォルダの中に、789jpg をそれぞれおいてください。画像はなんでもいいです。
    |[A]       |[B]|[C]       |[D]|[E]       |[F]|[G]    
 [1]|親フォルダ|┬ |子フォルダ|┬ |孫フォルダ|─ |789.jpg
 [2]|          |└ |123.jpg   |├ |456.jpg   |   |       
 [3]|          |   |          |└ |このブック|   |       

 3)シートに開発タブ>挿入>ActiveXコントロールのイメージコントロールを3つおいてください。
 4)シートモジュールに下記のコードを張り付けてください。
 5)VBEの画面から、表示>イミディエイトウィンドウを表示させてください
 6)F8を押して、4)のコードを実行してください。
    Option Explicit
    Sub test()
        Debug.Print CurDir
        ChDir ThisWorkbook.Path
        Debug.Print CurDir
        Image1.Picture = LoadPicture("..\123.jpg")
        Image2.Picture = LoadPicture("456.jpg")
        Image3.Picture = LoadPicture("孫フォルダ\789.jpg")
    End Sub

 これでなんとなくわかってもらえるとありがたいです。
   
(稲葉) 2019/01/10(木) 14:19

雰囲気を悪くしてしまったのは日を改めて特に申し訳なかったと感じております。

???様のおっしゃる通りで、成功したのは現段階では「\フォルダ名\ファイル名.jpg」と書いた時です。現段階というのは、とりあえず成功したのでパスは一旦置いておいて他の作業へ移って、ChDirやCurDirを試していないためです。
\ と / もOSの違いなのですね。

稲葉様ありがとうございます。試してみました。
確かに相対パスで画像を表示できました。ただし、イミディエイトウィンドウには同じパス(ブックのパス)が表示されました。
チェンジディレクトリを行う前と後のカレントディレクトリが同じであったという意味です。
たとえ同じであってもChDirを使わないと相対パスで画像の取得をすることはできないのでしょうか?
(アイス) 2019/01/10(木) 16:31


稲葉さんのマクロを実行する前に、Excelの「ファイル」−「開く」を使って、他の階層をブラウズした後、ファイルを開かずに閉じてみてください。

最後に見たフォルダがカレントになっているはずです。(ChDir関数と同じ効果) ブックを開いた直後は、カレントが、ThisWorkbook.Path だ、というだけ。 このように、カレントが何処なのかは意図せぬときに変わる可能性があるので、相対パスでファイル指定するのは止めた方が良いです。

今回のようなプログラムならば、シートに記述するのはファイル名だけにして、「\フォルダ名\」部分はマクロ内に定数定義してしまい、Thisworkbook.Path & 定数名 & vw(2) のようにするのがベストかと思います。 これなら、フォルダ名を変更した場合でも、いちいちシートを直さずとも、定数定義を変えるだけですから。(画像によって置いてあるフォルダが違う、という訳でも無いのでしょう?)
(???) 2019/01/10(木) 17:02


???様ありがとうございます。

カレントフォルダはアクティブになっているフォルダとは別とはなんとなく理解していましたが、このような場合等で変わってしまうのですね。

画像は全て同じファイルへ入れます。確かに、ファイルを分けていたらまた別の処理が必要になりますね。

ブックやフォルダの構成は変えないようにして、このまま(ThisWorkbook.Path & イラストのパス)のコーディングにします。

(アイス) 2019/01/10(木) 17:14


コメント返信:

[ 一覧(最新更新順) ]


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