Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


651 / 2272 ツリー ←次へ | 前へ→

【10633】エクセルに値渡ししたい ON 08/10/29(水) 13:55 質問[未読]
【10635】Re:エクセルに値渡ししたい neptune 08/10/29(水) 22:32 回答[未読]
【10676】Re:エクセルに値渡ししたい ON 08/11/6(木) 15:55 質問[未読]
【10678】Re:エクセルに値渡ししたい neptune 08/11/6(木) 17:22 発言[未読]
【10709】Re:エクセルに値渡ししたい ON 08/11/10(月) 11:14 質問[未読]
【10710】Re:エクセルに値渡ししたい neptune 08/11/10(月) 13:36 回答[未読]
【10715】Re:エクセルに値渡ししたい ON 08/11/10(月) 16:11 質問[未読]
【10716】Re:エクセルに値渡ししたい ON 08/11/10(月) 17:12 発言[未読]
【10717】Re:エクセルに値渡ししたい neptune 08/11/10(月) 18:50 回答[未読]
【10722】Re:エクセルに値渡ししたい ON 08/11/11(火) 9:17 お礼[未読]
【10733】Re:エクセルに値渡ししたい ON 08/11/13(木) 15:15 お礼[未読]
【10720】Re:エクセルに値渡ししたい neptune 08/11/10(月) 21:52 発言[未読]
【10711】Re:エクセルに値渡ししたい neptune 08/11/10(月) 13:38 発言[未読]

【10633】エクセルに値渡ししたい
質問  ON  - 08/10/29(水) 13:55 -

引用なし
パスワード
   こんにちは
よろしくお願い致します


エクセルを開いて、エクセルマクロを実行し、
その結果をアクセスにインポートしています


    Set xls = CreateObject("Excel.Application")

    Set wkb _
      = xls.Workbooks.Open( _
          Filename:=CurrentProject.Path & "\foo.xls")

    xls.Run "一括処理"

    wkb.Close SaveChanges:=True
    xls.Quit


    ・・・・

    DoCmd.TransferSpreadsheet・・・・


でこの時

エクセルで、 hoge を
Const hoge As String = "fuga"
のようにして使用しているのですが

アクセスフォームのリストボックスの値を
list_str = Me.リスト0.Column(1)
として

xls.Run "一括処理",list_str

のように、値渡ししたいと思っているのですが
どのように記述すればいいのかわかりません

アドバイスよろしくお願い致します

【10635】Re:エクセルに値渡ししたい
回答  neptune  - 08/10/29(水) 22:32 -

引用なし
パスワード
   ▼ON さん:
こんにちは

>エクセルで、 hoge を
>Const hoge As String = "fuga"
>のようにして使用しているのですが
>
>アクセスフォームのリストボックスの値を
>list_str = Me.リスト0.Column(1)
>として
>
>xls.Run "一括処理",list_str
>
>のように、値渡ししたいと思っているのですが
Excel側の"一括処理"に引数を持たせなければなりません。

sub 一括処理(byval pstr as string)
・・・

従って
>Const hoge As String = "fuga"
を使用しないようにすべきと思います。

例えば
sub 一括処理(optional byval pstr as string="fuga")
とするとか。

方法はお好きなものにどうぞ。

【10676】Re:エクセルに値渡ししたい
質問  ON  - 08/11/6(木) 15:55 -

引用なし
パスワード
   ▼neptune さん ありがとうございます

なぜだか、うまく動かせずに
ググッたり、試したりしているうちに、大変遅くなってしまいました


結局、下記でなんとか動きましたが

Sub 一括処理2(Optional ByVal pstr As String)
のとき
'xls.Run "一括処理2"   '←NG 引数は省略できません。
となってしまいます
オプショナルだから引数は無しでもいいような気がするのですが・・・
アドバイス頂けると助かります

よろしくお願い致します


アクセス標準モジュール

  Public Sub run_excel2() 
    
    
    '参照設定時
    'Dim xls As Excel.Application
    'Dim wkb As Excel.Workbook
    'Dim wks As Excel.Worksheet
    'Dim rng As Excel.Range
    'Dim strSQLstring As String
    
    'レイトバインド時(参照設定無し)
    Dim xls As Object
    Dim wkb As Object
    Dim wks As Object
    Dim rng As Object
    Dim strSQLstring As String
    
    Dim pstr As String
    
    pstr = "ac_str"
    
    Set xls = CreateObject("Excel.Application")
    
    xls.Visible = True   '###
         
    Set wkb _
      = xls.Workbooks.Open( _
          Filename:=CurrentProject.Path & "\test_01.xls")
         
    xls.Run "一括処理1"  '←OK 引数なし 動きます
    'xls.Run "一括処理2"   '←NG 実行時エラー '449':引数は省略できません。
    xls.Run "一括処理2", pstr   '←OK 引数有りなら動きます
    
  '   wkb.Close SaveChanges:=True
  '   xls.Quit
  '   Set wks = Nothing
  '   Set wkb = Nothing
  '   Set xls = Nothing
        
  
  End Sub


エクセル標準モジュール

Public Sub 一括処理1()

  Dim exl_msg As String
  
  exl_msg = "exl固定"
  
  MsgBox exl_msg


End Sub


Sub 一括処理2(Optional ByVal pstr As String)
'Sub 一括処理2(pstr As String)

    
  MsgBox pstr
  

End Sub

【10678】Re:エクセルに値渡ししたい
発言  neptune  - 08/11/6(木) 17:22 -

引用なし
パスワード
   ▼ON さん:
こんにちは

Excelの方はコピペ、Accessの方もパスを変更しただけ。
コードは以下。
Public Sub run_excel2()
    'レイトバインド時(参照設定無し)
    Dim xls As Object
    Dim wkb As Object
    Dim wks As Object
    Dim rng As Object
    Dim strSQLstring As String
  
    Dim pstr As String
  
    pstr = "ac_str"
  
    Set xls = CreateObject("Excel.Application")
  
    xls.Visible = True   '###
     
    Set wkb _
      = xls.Workbooks.Open( _
          Filename:="E:\hoge" & "\test_01.xls")
     
    xls.Run "一括処理1"  '←OK 引数なし 動きます
    xls.Run "一括処理2"   '←NG 実行時エラー '449':引数は省略できません。
                'OKでした。
    xls.Run "一括処理2", pstr   '←OK 引数有りなら動きます
  
    wkb.Close SaveChanges:=True
    xls.Quit
    Set wkb = Nothing
    Set xls = Nothing
End Sub

で、確認しましたが、問題なく動作しました。
VB6でも上記で検証しましたが、やはり、問題は発生しませんでした。
なので、何故、エラーが出るかは?です。

念の為、Bookの破損を切り分ける為、
新しいBookを作成して、検証をやり直してみてはどうですか?
この辺りしか思い付きません。

なお、当方、Office2K、WindowsXP SP3の環境です。

【10709】Re:エクセルに値渡ししたい
質問  ON  - 08/11/10(月) 11:14 -

引用なし
パスワード
   遅くなりました

▼neptune さん 検証して頂きありがとうございます

>で、確認しましたが、問題なく動作しました。
>VB6でも上記で検証しましたが、やはり、問題は発生しませんでした。
>なので、何故、エラーが出るかは?です。

>念の為、Bookの破損を切り分ける為、
>新しいBookを作成して、検証をやり直してみてはどうですか?
>この辺りしか思い付きません。

再起動後、同一ブックでエラーは発生しなくなりました
これで、他のアプリケーションに、引数渡しすることが出来るようになりました
ありがとうございました。


今まで、同一アプリケーション内では通常
function関数で処理させ戻り値を利用することばかりでした
ということで、これらは
特に意識することなく参照渡し ByRefで使用していました
今回の件名で、値渡ししたいということで、この辺がわからないまま
ためしていたので??の状態だったようです


>ググッたり、試したりしているうちに、大変遅くなってしまいました
について理解のないままではまずいと振り返ってみました

通常は
  Function new_str(n_str1 As String, n_str2 As String) As String
    
    new_str = n_str1 & str2
    
  End Function

  Sub get_str()
  
    Dim str1 As String
    Dim str2 As String
    
    str1 = "hoge"
    str2 = " fuga"
    
    Debug.Print new_str(str1, str2)
    
  End Sub
のような利用の仕方しています

今回の
>なぜだか、うまく動かせずに
は、下記のような場合で、下記、変に加工するとすぐエラーになってしまい
うまく修正することは出来ないのですが

ByValの時は123のようになるよな気がするのですが hoge fuga になってしまいます

基本がわかっていないので、コード自体が変かもしれませんが
アドバイス頂けるとうれしいですよろしくお願い致します

  Sub Test()
  
    Dim str1 As String
    Dim str2 As String
    Dim out As String
    
    str1 = "hoge"
    str2 = " fuga"
    out = "123"
        
    'Call ByVal_str(str1, str2, out)
    Debug.Print "Test1:" & ByVal_str(str1, str2, out)
    
    'Call ByRef_str(str1, str2, out)
    Debug.Print "Test2:" & ByRef_str(str1, str2, out)


  End Sub

  Function ByVal_str(ByVal idx1 As String, ByVal idx2 As String, ByVal modori As String) As String
    
    ByVal_str = idx1 & idx2
    Debug.Print "ByVal_str:" & ByVal_str
    
  End Function
  
  
  Function ByRef_str(ByVal idx1 As String, ByVal idx2 As String, ByRef modori As String) As String
    
    ByRef_str = idx1 & idx2
    Debug.Print "ByRef_str:" & ByRef_str
    
  End Function


ByVal_str:hoge fuga
Test1:hoge fuga
ByRef_str:hoge fuga
Test2:hoge fuga

  

【10710】Re:エクセルに値渡ししたい
回答  neptune  - 08/11/10(月) 13:36 -

引用なし
パスワード
   ▼ON さん:
こんにちは

////////////一番大きな違い////////////
値渡し:
渡したいデータをコピーして、コピーしたデータへの参照を渡す。
従って、コピーしたデータを関数などで弄くっても元のデータには影響を及ぼさない

参照渡し:
渡したいデータが格納されているデータへの参照を渡す。
関数などでこのデータ弄くると、元のデータを弄くることになり、
元のデータに影響を及ぼすことになる。
////////////////////////////////////
↑を踏まえた上で下記を読んで下さい。

解説をちょっと書いてみました。
Sub Test()
' ByValの時は123のようになるよな気がするのですが hoge fuga になってしまいます

    Dim str1 As String
    Dim str2 As String
    Dim out As String
    Dim ret As Long
  
    str1 = "hoge"
    str2 = " fuga"
    out = "123"
    
    ' 変数outは渡しているが、Functionで処理されていない。
    '従って、変数outの内容はByVal_strの戻り値には全く関係ない。
    Debug.Print "Test1:" & ByVal_str(str1, str2, out)
  
    '上記と同じ
    Debug.Print "Test2:" & ByRef_str(str1, str2, out)
    
    '結果としてはByVal_st、ByRef_strは同じ処理をしている。
    'ByVal、ByRefは関係ない。
    
    '参照渡しの戻り値を使い且つ、関数の戻り値を使う場合はこんな場合
    'もあります。(たまにですが)
    ret = sample(str1, str2, out)
    Debug.Print "sample : sample(str1, str2, out)"
    Debug.Print "結合された文字列 :" & out
    Debug.Print "結合された文字列の文字数 :" & ret & "個"
    
End Sub

'sample:渡された文字列を結合した文字列を返す
'引数 pret:pa、pb を結合したデータを格納する
Function sample(ByVal pa As String, ByVal pb As String, ByRef pret As String) As Long
  On Error GoTo trap
  pret = pa & pb
  sample = Len(pret)
  Exit Function
trap:
  sample = 0
End Function
Function ByVal_str(ByVal idx1 As String, ByVal idx2 As String, ByVal modori As String) As String

  ByVal_str = idx1 & idx2
  Debug.Print "ByVal_str:" & ByVal_str
End Function

Function ByRef_str(ByVal idx1 As String, ByVal idx2 As String, ByRef modori As String) As String

  ByRef_str = idx1 & idx2
  Debug.Print "ByRef_str:" & ByRef_str
End Function

【10711】Re:エクセルに値渡ししたい
発言  neptune  - 08/11/10(月) 13:38 -

引用なし
パスワード
   ▼ON さん:
訂正
誤:'sample:渡された文字列を結合した文字列を返す
正:'sample:渡された文字列を結合した文字列の文字数を返す

【10715】Re:エクセルに値渡ししたい
質問  ON  - 08/11/10(月) 16:11 -

引用なし
パスワード
   解説ありがとうございます

"一番大きな違い" は、文言として理解できます・・・
折角コードをアップ頂いていますが頭が固くて (T_T)

お手数ですが下記が理解できないと前に進めそうもありません
'F_ByValS:6 元値でなく加工値はなぜ??
アドバイス頂けるとうれしいです よろしくお願い致します

Sub ByRef_ByVal()

  Dim str As String
  
  str = "Ref"
  S_ByRef str
  Debug.Print "S_ByRef:" & str  'S_ByRef:123 '参照渡し(ByRef) 加工値
  Debug.Print
  
  str = "Val"
  S_ByVal str
  Debug.Print "S_ByVal:" & str  'S_ByVal:Val '値渡し(ByVal) 元値
  Debug.Print
  
  Debug.Print "F_ByRefS:" & F_ByRef(2) 'F_ByRefS:4 加工値
  Debug.Print
  
  Debug.Print "F_ByValS:" & F_ByVal(2) 'F_ByValS:6 元値でなく加工値はなぜ??
  

End Sub

Sub S_ByRef(ByRef arg1 As String)  '参照渡し(ByRef)
  Debug.Print "S_ByRef_S:" & arg1 'S_ByRef_S:Ref
  arg1 = "123"
  Debug.Print "S_ByRef_E:" & arg1 'S_ByRef_E:123
  Debug.Print
End Sub


Sub S_ByVal(ByVal arg1 As String)  '値渡し(ByVal)
  Debug.Print "S_ByVal_S:" & arg1 'S_ByVal_S:Val
  arg1 = "123"
  Debug.Print "S_ByVal_E:" & arg1 'S_ByVal_E:123
  Debug.Print
End Sub


Function F_ByRef(ByRef arg1 As Integer)  '参照渡し(ByRef)

  F_ByRef = arg1 * 2
  Debug.Print "F_ByRefF:" & F_ByRef 'F_ByRef:4
  Debug.Print

End Function

Function F_ByVal(ByVal arg1 As Integer)  '値渡し(ByVal)

  F_ByVal = arg1 * 3
  Debug.Print "F_ByValF:" & F_ByVal 'F_ByValF:6
  Debug.Print
  
End Function

【10716】Re:エクセルに値渡ししたい
発言  ON  - 08/11/10(月) 17:12 -

引用なし
パスワード
   追記です


ご提示頂いたコードで下記 追記※ をしてみました
結果
    ' 変数outは渡しているが、Functionで処理されていない。
    '従って、変数outの内容はByVal_strの戻り値には全く関係ない。

    '結果としてはByVal_st、ByRef_strは同じ処理をしている。
    'ByVal、ByRefは関係ない。
となっているのですが

  Debug.Print "S_ByVal:" & str  'S_ByVal:Val '値渡し(ByVal) 元値
の動作とは異なっている・・・
頭がうにうにの状態です・・・
何かありましたらよろしくお願い致します


追記コード

Sub Test()
' ByValの時は123のようになるよな気がするのですが hoge fuga になってしまいます

    Dim str1 As String
    Dim str2 As String
    Dim out As String
    Dim ret As Long
 
    str1 = "hoge"
    str2 = " fuga"
    out = "123"
  
    ' 変数outは渡しているが、Functionで処理されていない。
    '従って、変数outの内容はByVal_strの戻り値には全く関係ない。
    Debug.Print "Test1:" & ByVal_str(str1, str2, out)
    Debug.Print out '追記※1
 
    '上記と同じ
    Debug.Print "Test2:" & ByRef_str(str1, str2, out)
    Debug.Print out '追記※2
  
    '結果としてはByVal_st、ByRef_strは同じ処理をしている。
    'ByVal、ByRefは関係ない。
  
    '参照渡しの戻り値を使い且つ、関数の戻り値を使う場合はこんな場合
    'もあります。(たまにですが)
    ret = sample(str1, str2, out)
    Debug.Print "sample : sample(str1, str2, out)"
    Debug.Print "結合された文字列 :" & out
    Debug.Print "結合された文字列の文字数 :" & ret & "個"
  
End Sub

'sample:渡された文字列を結合した文字列を返す
'引数 pret:pa、pb を結合したデータを格納する
Function sample(ByVal pa As String, ByVal pb As String, ByRef pret As String) As Long
  On Error GoTo trap
  pret = pa & pb
  sample = Len(pret)
  Exit Function
trap:
  sample = 0
End Function
Function ByVal_str(ByVal idx1 As String, ByVal idx2 As String, ByVal modori As String) As String

  ByVal_str = idx1 & idx2
  Debug.Print "ByVal_str:" & ByVal_str
  Debug.Print "ByVal_str modori:" & modori '追記※3
  
End Function

Function ByRef_str(ByVal idx1 As String, ByVal idx2 As String, ByRef modori As String) As String

  ByRef_str = idx1 & idx2
  Debug.Print "ByRef_str:" & ByRef_str
  Debug.Print "ByRef_str modori:" & modori '追記※4
  
End Function

【10717】Re:エクセルに値渡ししたい
回答  neptune  - 08/11/10(月) 18:50 -

引用なし
パスワード
   ▼ON さん:
こんにちは

この辺りは非常に大事ですから落ち着いてゆっくり考えてください。

先ずテストで使っているByVal_str2とByRef_str2は検証用としては
全く不適当です。
なぜなら、関数内では引数以外modoriが出てこない
下記の2つの関数と等価です。
Function ByVal_str2(ByVal idx1 As String, ByVal idx2 As String) As String
  ByVal_str2 = idx1 & idx2
End Function

Function ByRef_str2(ByVal idx1 As String, ByVal idx2 As String) As String
  ByRef_str2 = idx1 & idx2
End Function

次にsut testですが、長くなるので必要部分のみ引用しますが、上に記したように
関数によって、outは変更されません。従って、以下のようになります。

    str1 = "hoge"
    str2 = " fuga"
    out = "123"     '代入A
 
    ' 変数outは渡しているが、Functionで処理されていない。
    '従って、変数outの内容はByVal_strの戻り値には全く関係ない。
    Debug.Print "Test1:" & ByVal_str(str1, str2, out)
    Debug.Print out '追記※1 ←は代入Aで代入したデータが全く変化していない

    '上記と同じ
    Debug.Print "Test2:" & ByRef_str(str1, str2, out)
    Debug.Print out '追記※2 ←は代入Aで代入したデータが全く変化していない
 
    '結果としてはByVal_st、ByRef_strは同じ処理をしている。
    'ByVal、ByRefは関係ない。

で、冷静に考えればこの程度はそんなにややこしくないので、
Helpの
Visual Basicプログラミングのヒント
  --引数の効率的な引き渡し
に引数について説明しています。サンプルもあります。
この辺りを冷静に読んでみてはいかがですか?

それと、「VB 値渡し 参照渡し」でググって見たんですが、沢山解説も
ヒットします。それらもご覧になって下さい。
ht tp://www001.upp.so-net.ne.jp/yoshihiro/gram4.htm
は判りやすそうです。

ちょっと難しくなり、言語もvb.netですが、概念も用語もVBAと同じです。
ht tp://msdn.microsoft.com/ja-jp/library/ddck1z30(VS.80).aspx

理解できるまで考えないと、見通しのよいプログラムが書きにくいとか、
この絡みでバグが出た時、大変困りますので、頑張って下さい。

理解しにくい点があれば、質問してください。わかる範囲なら相談にのります。

【10720】Re:エクセルに値渡ししたい
発言  neptune  - 08/11/10(月) 21:52 -

引用なし
パスワード
   ▼ON さん:
すみません。今見たら誤記がありました。
誤:先ずテストで使っているByVal_str2とByRef_str2は検証用としては
正:先ずテストで使っているByVal_strとByRef_strは検証用としては

【10722】Re:エクセルに値渡ししたい
お礼  ON  - 08/11/11(火) 9:17 -

引用なし
パスワード
   ▼neptune さん ありがとうございます

お手数おかけします

>先ずテストで使っているByVal_str2とByRef_str2は検証用としては
>全く不適当です。
>なぜなら、関数内では引数以外modoriが出てこない
>下記の2つの関数と等価です。


>理解できるまで考えないと、見通しのよいプログラムが書きにくいとか、
>この絡みでバグが出た時、大変困りますので、頑張って下さい。

了解です


>Visual Basicプログラミングのヒント
>  --引数の効率的な引き渡し
>に引数について説明しています。サンプルもあります

自宅のOffice2Kでは、上記ヘルプを見つけることが出来ましたが
会社のOffice2003には無いようです

ちょっと時間が掛かるかもしれませんが、ご紹介頂いたURL等参考に勉強してみます

>理解しにくい点があれば、質問してください。わかる範囲なら相談にのります。
お気遣いありがとうございます

解決できない疑問がでた場合は、またQさせて頂きたいと思います

その時には、よろしくお願い致します

とりあえずのお礼でした

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

【10733】Re:エクセルに値渡ししたい
お礼  ON  - 08/11/13(木) 15:15 -

引用なし
パスワード
   遅くなりました
ぐぐりまくって
動作できるサンプルで
脳みそが うにうに → うに
ぐらいになりましたが・・・
まとめとしてアップできるような状況ではありません

絡み合いが凄すぎて・・・みたいな感じなんですが
下記関連事項をあいまいにしてきたことが
原因とおもわれました


■ Call と括弧と引数の微妙な三角関係
tp://shadowslasheizan.blog114.fc2.com/blog-entry-87.html

■ 参照方法、値渡しと参照渡しを明示しよう!
tp://home.att.ne.jp/zeta/gen/excel/c04p11.htm


同一プロジェクト内では参照渡しは可能ですが、
別プロジェクト(別ブック)では、ByRefを明示しても値渡し



Runメソッド
実行時バインディングで呼び出せばByRefも有効

か・・・


現在、とりあえずご教授いただいた方法で
他のアプリケーションに、引数渡しすることが出来ていますので
次回使用時等、少しずつ、うに の解消に努めて行きたいと思います

漠然としすぎていて申し訳ありませんが
上記で、今回の報告とさせていただきます

再質問が、別Q等であるかも知れませんが
そのときによろしくお願い致します

ありがとうございました

651 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078198
(SS)C-BOARD v3.8 is Free