[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Applicationを格納したら…』(ngk)
こんにちは。
これが必要なのかは置いておいて、
Dim App As New Application
Dim xlsF As WorksheetFunction
Set xlsF = App.WorksheetFunction
として、エクセル関数を使った時と
Dim App As Application
Dim xlsF As WorksheetFunction
Set App = Application
Set xlsF = App.WorksheetFunction
として、エクセル関数を使った時とで
計算結果が同じ時と違う時があるのは何故でしょうか?
ご存知の方は教えてもらえたら幸甚です。
< 使用 Excel:unknown、使用 OS:unknown >
(隠居Z) 2022/08/10(水) 17:37
Option Explicit Public v() Sub t1() Dim App As New Application Dim xlsF As WorksheetFunction Set xlsF = App.WorksheetFunction v = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) MsgBox xlsF.Sum(v) t2 End Sub Private Sub t2() Dim App As Application Dim xlsF As WorksheetFunction Set App = Application Set xlsF = App.WorksheetFunction MsgBox xlsF.Sum(v) End Sub 10回くらいだと計算結果はおなじでした excel 2016 win 10 でした。 (隠居Z) 2022/08/10(水) 17:49
勿論、不思議に思う気持ちや、そうした質問をすることは大切と思います。
(γ) 2022/08/10(水) 17:53
これ同じです。エラー値返せません。
実行エラー。
Vlookup なども同じ。
Application.Vlookup
などは、office95の時の書き方で、2000以降で消すつもりだった?のに
未だに残ってる感じ。
エラートラップでかわすより、こっちの方がよく使われるから???
重宝してます。
(まだ16) 2022/08/10(水) 20:02
質問者さんのサンプルコードは Appllcationのインスタンスが違うだけなので、 インスタンスが違うと関数の結果が違うのというのも不思議な話ですが、 その事象を確認できるコードやサンプルデータの提示をお願いします。
Application.Match と Application.WorksheetFunction.Match の 挙動の違いともまたちょっと違いますよね (´・ω・`) 2022/08/10(水) 20:13
挙動の違いですか? 詳しくは解りませんが、こういうやつですかね?
Sub tes1() dd = Application.CountIf(Range("A1:A15"), Range("A1:A15"))
For Each nn In dd MsgBox nn Next MsgBox dd(1, 1) End Sub
Sub tes2() dd = WorksheetFunction.CountIf(Range("A1:A15"), Range("A1:A15"))
For Each nn In dd MsgBox nn Next MsgBox dd(1, 1) End Sub (まだ16) 2022/08/11(木) 08:39
念のため書いておきますが、 質問者さんの主張は、以下の様な場合に、結果が異なる場合があるといってます (どんな関数かは書いてないので、SUM関数とは限りません。あくまで例として)
Sub sample() Dim thisApp As Application Dim newApp As Application Dim ret1 As Variant, ret2 As Variant Dim sumRange As Range
Set thisApp = Application ' 質問者さんの2つのコードの本質的な違いは Set newApp = New Application ' この2行の違いです
newApp.Visible = True
Set sumRange = ThisWorkbook.Worksheets(1).Range("A1:A10") For i = 1 To 10 sumRange.Cells(i, 1).Value = Rnd * 100 Next
ret1 = thisApp.WorksheetFunction.Sum(sumRange) ret2 = thisApp.WorksheetFunction.Sum(sumRange)
Debug.Print ret1, ret2, ret1 = ret2 End Sub
私はそんな訳ないでしょという立場です (´・ω・`) 2022/08/11(木) 08:58
>私はそんな訳ないでしょという立場です
あれ、(´・ω・`)さんへの返信に見えましたか、 すみません。 私も同じです。
多分質問者は、エラートラップしているのだと思います。 で、結果が返ったのか、デフォルト値のままなのかが まだよく解ってないのかも? (まだ16) 2022/08/11(木) 09:10
あわわ、完全に質問を読み違えていました。失礼しました。 実例を知りたいですね。
(γ) 2022/08/11(木) 13:56
私が実際に起きた例で行くと
標準モジュール(仮にSampleとします)に
Option Explicit
'共通のオブジェクト
Public App As New Application
Dim xlsF As WorksheetFunction
としてクラスモジュールに
Public Sub Test
Set Sample.xlsF = App.WorksheetFunction With まとめファイル.Worksheets(1) Dim cnt As Long: cnt = Sumple.xlsF.CountA(.Range("C:C"))
としたとき、C列がすべて空欄(""やスペースではなく)であるにも関わらす
cntの値が1048576になってしまったので、
イミディエイトウィンドウでNewで宣言した場合とNewを付けずSetで格納した場合とで
cntの値が変わった、という現象が起きました。
同じ使い方をしても他のファイルでは正しく動いてたので何故かな。。と思いまして
(ngk) 2022/08/12(金) 07:56
Newで宣言した場合とNewを付けずSetで格納した場合とで
イミディエイトウィンドウで確認したところ
cntの値がNewありは1048576、Setで格納は0と
違う結果を示した、という現象が起きました。
に変えてく下さい。
(ngk) 2022/08/12(金) 11:01
Option Explicit
Public NewApp As New Application
Public ThisNewApp As Application
Public ThisApp As Application
Public NewWsF As WorksheetFunction
Public ThisNewWsF As WorksheetFunction
Public ThisWsF As WorksheetFunction
Sub test()
Set ThisApp = Application Set ThisNewApp = New Application Set NewWsF = NewApp.WorksheetFunction Set ThisWsF = ThisApp.WorksheetFunction Set ThisNewWsF = ThisNewApp.WorksheetFunction
Dim NewWb As Workbook Set NewWb = Workbooks.Add
With NewWb.Worksheets(1)
Debug.Print NewWsF.CountA(.Range("A:A")) Debug.Print ThisNewWsF.CountA(.Range("A:A")) Debug.Print ThisWsF.CountA(.Range("A:A")), "End"
End With
With Workbooks("作成フォルダまとめ.xlsx").Worksheets(1)
Debug.Print NewWsF.CountA(.Range("A:A")) Debug.Print ThisNewWsF.CountA(.Range("A:A")) Debug.Print ThisWsF.CountA(.Range("A:A")), "End"
End With End Sub
結果:
1048576 1048576 0 End 1048576 1048576 0 End
Newを付けたらダメらしいです。
理由はわかりません。
>同じ使い方をしても他のファイルでは正しく動いてたので
同じ使い方をしているファイルはありませんでした。
すみません。
(ngk) 2022/08/12(金) 11:44
Public Sub test() Dim App As Application Dim xlsF As WorksheetFunction Set App = New Application Set xlsF = App.WorksheetFunction
With ThisWorkbook.Worksheets(1) Dim cnt As Long: cnt = xlsF.CountA(.Range("C:C")) Debug.Print cnt End With App.Quit End Sub
再現しました。イミディエイトウィンドウに 1048576 と出力されました。
WorksheetFunctionのApplicationのインスタンスと、ThisWorkbookのApplicationのインスタンスが異なるのが、気持ち悪いので、
Public Sub test1() Dim App As Application Dim xlsF As WorksheetFunction Set App = New Application Set xlsF = App.WorksheetFunction
With App.Workbooks.Open(ThisWorkbook.FullName, , True) Dim cnt As Long: cnt = xlsF.CountA(.Worksheets(1).Range("C:C")) Debug.Print cnt .Close End With App.Quit End Sub
別インスタンスのApplicationでブックを開いて、それを対象にしたら、0 が出力されました。
別インスタンスのApplicationのブックは参照できないような気かするのでエラーになるのが自然な気かしますが、なぜ、 1048576が返るのかは謎です。
(hatena) 2022/08/12(金) 11:49
Sub test()
#Const flg = 1
Dim App As Application Dim Func As WorksheetFunction
#If flg = 1 Then
Set App = New Application #Else Set App = Application #End If
Set Func = App.WorksheetFunction
MsgBox Func.CountA(ThisWorkbook.Worksheets(1).Range("A:A")) End Sub
>cntの値がNewありは1048576
現象を確認しました。
なぜそうなるかの見解は識者の方に。。。。
(まっつわん) 2022/08/12(金) 12:02
現象を確認しました。 >私はそんな訳ないでしょという立場です 撤回してお詫び申し上げます。 原因・理由はわかりませんが。 (´・ω・`) 2022/08/12(金) 14:34
原因の「推測」ですけども、
別インスタンスのWorksheetFunctionにThsiworkbookのRangeオブジェクトが渡されているかに見えますが、 規定値(Valueプロパティ)が渡されているに過ぎず、全データが値ありとしてカウントされる。
一方、当インスタンスのWorksheetFunctionは間違いなくThsiworkbookのRangeオブジェクトが渡されているので、 その関数の仕様によって、Empty値は排除されてカウントされる。
Sub test() Dim App As Application
Set App = New Application
With ThisWorkbook.Worksheets(1) .Range("A1").Value = 1 .Range("A2").Value = Empty .Range("A3").Value = "A"
Debug.Print WorksheetFunction.CountA(.Range("A1:A3")) '2 Debug.Print WorksheetFunction.CountA(.Range("A1:A3").Value) '3
Debug.Print App.WorksheetFunction.CountA(.Range("A1:A3")) '3 End With End Sub
(半平太) 2022/08/12(金) 14:58
それぞれのインスタンスでやってみた結果
Option Explicit
Public NewApp As New Application
Public ThisNewApp As Application Public ThisApp As Application Public NewWsF As WorksheetFunction Public ThisNewWsF As WorksheetFunction Public ThisWsF As WorksheetFunction
Sub test()
Set ThisApp = Application Set ThisNewApp = New Application Set NewWsF = NewApp.WorksheetFunction Set ThisWsF = ThisApp.WorksheetFunction Set ThisNewWsF = ThisNewApp.WorksheetFunction
Dim NewWb As Workbook Set NewWb = ThisApp.Workbooks.Add
With NewWb.Worksheets(1) Debug.Print NewWsF.CountA(.Range("A:A")) Debug.Print ThisNewWsF.CountA(.Range("A:A")) Debug.Print ThisWsF.CountA(.Range("A:A")), "End" End With
ThisApp.DisplayAlerts = False NewWb.Close ThisApp.DisplayAlerts = True
Set NewWb = NewApp.Workbooks.Add
With NewWb.Worksheets(1) Debug.Print NewWsF.CountA(.Range("A:A")) Debug.Print ThisNewWsF.CountA(.Range("A:A")) Debug.Print ThisWsF.CountA(.Range("A:A")), "End" End With
ThisApp.DisplayAlerts = False NewWb.Close ThisApp.DisplayAlerts = True
Set NewWb = ThisNewApp.Workbooks.Add
With NewWb.Worksheets(1) Debug.Print NewWsF.CountA(.Range("A:A")) Debug.Print ThisNewWsF.CountA(.Range("A:A")) Debug.Print ThisWsF.CountA(.Range("A:A")), "End" End With
ThisApp.DisplayAlerts = False NewWb.Close ThisApp.DisplayAlerts = True
End Sub
結果:
1048576 1048576 0 End 0 1048576 1048576 End 1048576 0 1048576 End
(ngk) 2022/08/12(金) 16:45
Rangeオブジェクトには直接関係しないケースで 別インスタンスのWorksheetFunctionが異なる挙動をする例がありましたので報告します。 (なんと、別インスタンスの方が高性能になった)
Sub test() Dim Ary36 Dim Ary37 Dim AppOwn As Application Dim AppNew As Application
Set AppOwn = Application Set AppNew = New Application
Columns("A").ClearContents
Range("A65536") = 36 'ターゲットに36を入力 Range("A65537") = 37 'ターゲットに37を入力
Ary36 = Range("A1:A65536").Value '値配列作成 Ary37 = Range("A1:A65537").Value '値配列作成
Debug.Print AppOwn.WorksheetFunction.Match(36, Ary36, 0) ' →65536 Debug.Print AppNew.WorksheetFunction.Match(36, Ary36, 0) ' →65536
Debug.Print AppOwn.WorksheetFunction.Match(37, Ary37, 0) ' →実行時エラー Debug.Print AppNew.WorksheetFunction.Match(37, Ary37, 0) ' →65537 End Sub
通常、Lookup系の関数は、第二引数(検索範囲)が65536個を越えた場合、 セル範囲なら問題は起きませんが、値配列の場合は#NAエラーになります。
不可解な仕様なので、バグと呼んでもいいのでしょうが、その評価は置くとして、 この振る舞いを利用して、両者に違いが出るか検証してみました。
自インスタンスは、予想通りエラーになりましたが、 他インスタンスは、チャンとヒットします。
(半平太) 2022/08/30(火) 11:21
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.