2016-04-30 17 views
0

VBAを使用してソルバーを使用したとき、この非常に奇妙なバグがありました。私の目的と変化するセルはシート1にあり、最適化されたソリューションが1つあるときは、最適化されたセルをシート2にコピーしたいと思います。ソルバープログラムでWorksheets(1).Selectを追加した場合、ソルバーは正常に動作し、値をシート2に貼り付けます。しかし、このステートメントを削除し、シート1ではなく選択したシート2でソルバーを実行すると、ステータスバーの「設定問題...」のようなものが最初に表示され、間違った結果と奇妙な「0」が表示されます私はVBAデバッガを使用し、ステートメントCall SolverSolve(True)の後にこの "0"の値が現れていることが分かりました。だから、バグはちょうどソルバーにあると思われます。アクティブなシートが変化するセルと目的のセルに存在する場合にのみソルバーを実行する必要がありますか?または私はどこで間違っているのですか?別のシートでVBAソルバーを扱うときに奇妙なバグがある

Option Explicit 
Function SAMPLEONCE() 
'Create one sample from 2500 MI data in worksheets("P2 MI Data"), the sample is 
'stored in worksheets("P2 Sample") 

    Const n As Long = 2500 
    Dim temp As Long 
    Randomize 
    temp = Int(Rnd * 2500) + 1 
    SAMPLEONCE = Worksheets("P2 MI Data").Cells(temp + 1, 1).Resize(1, 6) 
End Function 

Sub SolveItOnce() 

    Call solverreset 
    Call solverok(Worksheets("P2 Sample").Range("Output"), 2, 0, Worksheets("P2 Sample").Range("Input")) 
    Call solversolve(True) 
End Sub 
Sub SolveIt() 
    Dim i As Long, j As Long, k As Long 
    Application.ScreenUpdating = False 
    Application.Calculation = xlCalculationManual 
    Worksheets("P2 Sample").Activate 
    For i = 1 To 100 
     'Sampling 
     For j = 1 To 1000 
      Worksheets("P2 Sample").Range("Sample").Rows(j).FormulaArray = "=SAMPLEONCE()" 
     Next j 
     Worksheets("P2 Sample").Range("Sample").Copy 
     Worksheets("P2 Sample").Range("Sample").PasteSpecial Paste:=xlPasteValues 
     'Call Solver 
     For k = 1 To 3 
      Call SolveItOnce 
     Next k 
     'Output result 
     Worksheets("P2 Sample").Range("A2:G2").Copy 
     Worksheets("P2 Result").Range("A1:G1").Offset(i, 0).PasteSpecial Paste:=xlPasteValues 
    Next i 
    Application.Calculation = xlCalculationAutomatic 
End Sub 
+0

VBAでソルバーを使用するといくつかの欠点があります。 [この質問](http://stackoverflow.com/questions/36671991/use-solver-in-vba-with-loop-inrows)への回答を参照してください。 SolverResetを使わず、正しいアドレスを取得し、 'EngineDesc'を使わずに、あなたがしていることにすべて影響を与えるようなものがあります。 – OldUgly

+0

私の質問に具体的にコメントできますか? – Nicholas

+0

私は理解しています - あなたの質問にはもちろんコメントできます。コードのサンプルを投稿すると、より直接的なフィードバックを提供することができます。 – OldUgly

答えて

0

私は(もっと良い言葉の欠如のため)bug associated with the use SolverResetがあり...

Sub SolveItOnce() 

    Call solverreset 
    Call solverok(Worksheets("P2 Sample").Range("Output"), 2, 0, Worksheets("P2 Sample").Range("Input")) 
    Call solversolve(True) 
End Sub 

を完全なコードをレビューしますが、日常SolveItOnceを扱っていません。私はそれを省略することをお勧めします。 SolverOKへのお電話で問題が解決されます。

SolverOKを呼び出す場合、SetCellByChangeの入力は範囲ではなく文字列である必要があります。また、ソルバーが正しいシートを参照していることを確認するには、文字列の範囲をシート名で「完全修飾」することをお勧めします。私はこの(コンパイル、テストしません)...

Sub SolveItOnce() 
Dim myRng As Range, SetAddress As String, ChngAddress As String 

    Set myRng = Worksheets("P2 Sample").Range("Output") 
    SetAddress = Split(myRng.Address(external:=True), "[")(0) & Split(myRng.Address(external:=True), "]")(1) 

    Set myRng = Worksheets("P2 Sample").Range("Input") 
    ChngAddress = Split(myRng.Address(external:=True), "[")(0) & Split(myRng.Address(external:=True), "]")(1) 

    SolverOk SetCell:=SetAddress, MaxMinVal:=3, ValueOf:=1, ByChange:=ChngAddress, Engine:=1 
    SolverSolve UserFinish:=True 

    Set myRng = Nothing 
End Sub 

これは、ソルバーがやっている、あなたは、呼び出し元のルーチンで何をやっていることとの間の相互作用を防止すべきであるようにあなたのコードを見て何かをお勧めします。

設定Application.Calculation = xlCalculationManualは本当にあなたのために何もしません。ソルバーは、計算モードを自動的に設定し、そのように設定します。揮発性の数式(例:RAND()、またはNOW()、またはRANDBETWEEN()など)を使用している場合は、他の手口を行う必要があります。

更新 - アクティブシートIはSetCellByChangeアドレスがアクティブシート(驚くほど難しい)以外のシート上にあったことを認識するソルバーを強制することができた

を変更すると問題を、それが投げ以下のエラー...

enter image description here

enter image description here

これは、ソルバを実行する前にソルバ問題を含むワークシートをアクティブにすることに戻ります。以下は、あなたの古いアクティブシートが何であってもそれを保存し、それを再びアクティブにします。

Sub SolveItOnce() 
Dim SetRng As Range, ChngRng As Range 
Dim mySht As Worksheet 

    Set mySht = ActiveSheet 
    Worksheets("P2 Sample").Activate 

    Set SetRng = Worksheets("P2 Sample").Range("Output") 
    Set ChngRng = Worksheets("P2 Sample").Range("Input") 

    SolverOk SetCell:=SetRng.Address, MaxMinVal:=3, ValueOf:=1, ByChange:=ChngRng.Address, Engine:=1 
    SolverSolve UserFinish:=True 

    mySht.Activate 
    Set SetRng = Nothing 
    Set ChngRng = Nothing 
    Set mySht = Nothing 
End Sub 
+0

ありがとうございます、あなたのコードを試しましたが、私がシート2にいた場合でもバグがありました。ここでsheet2は "P2 Result"です – Nicholas

+0

OK - テストの問題をセットアップする必要があります。ありがとう。 – OldUgly

+0

ソルバールーチンは、MSによっていくつかの注意が必要です。私の答えを更新しました。 – OldUgly

関連する問題