Excel 2016 VBA solver constraints - vba

I am trying to run an automatic solver over a column of values. Target, reference and constraints cells are all in the same row, and they shift down with the target cell while running the solver throughout the column. The target cell has to be minimized, by changing the reference cell on the same row, under the constrain requiring to keep a third cell (that depends on the reference cell value) greater or equal than a fourth cell. None of the cells contain integers, all of them contain decimal values.
To resume:
Target cell (to be minimized) : P13
Reference cell (changing cell) : L13
Constrain (where M13 depends on L13) : M13 >= F13
all down to row 8795, shifting accordingly all the cells before mentioned.
The solver works fine running it manually row by row, but trying to automatize it in order to avoid 8762 iterations it doesn't respect the constrain. I have tried to remove " ", to add SolverReset and to put the constraint on top of the instructions, but nothing worked well. The code is:
Private Sub CommandButton1_Click()
Dim count As Integer
count = 13
Do While count <= 8795
SolverOk SetCell:=Cells(count, 16), MaxMinVal:=2, ByChange:=Cells(count, 12)
SolverAdd CellRef:=Cells(count, 13), Relation:=3, FormulaText:=Cells(count, 6)
SolverSolve userfinish:=True
count = count + 1
Loop
End Sub
I was trying to change constraint and I have noticed where probably the bug is: after running the code, if I open the solver I can see the last constraint used by the code. As you can see in the image below, I've tried to set a new constraint L13<=H13, where H13= 9,272 but the solver has 9272190.... maybe it is not "seeing" the decimal separator. Any idea?
Thank you for your time.

Related

Advise Solver Loop VBA

I am new to VBA and have a question.
in Excell, I estimated 3 values by using solver. The objective was set to an exact value, including there were 6 simple constraints.
Now I want to re-estimate these 3 values by only incrementally increasing the objective value (thus constraints stay the same).
I am thinking a using a loop in VBA but I have no idea where to start since I am no Pro in VBA.
can anyone help?
Ciao!
you can make a loop to adapt the target value for the solver via vba. In the vba editor you need to add reference to the solver (menu tools-> references-> check solver).
in the loop i is used to set the target, once the solution is found, the corresponding range B9:D9 is copied as from column F.
Dim i
For i = 1 To 40
SolverOk SetCell:="B21", MaxMinVal:=3, ValueOf:=i, ByChange:="B9:D9", Engine:= _
1, EngineDesc:="GRG Nonlinear"
SolverSolve True
Range("B9:D9").Copy Cells(i, "F")
Next i

VBA code using "Cells(Rows.count).Row).End(xlUp)" fails after 263 iterations

I am using a Sub of the form:
If Not Intersect(Target, Sheets("Sheet1").Range("A1")) Is Nothing Then (+ code)
in conjunction with:
Sheets("Sheet2").Range ("A1" & Cells(Rows.Count).Row).End(xlUp).Offset(1, 0).Value = Sheets("Sheet1").Range("A1").Value
with the intention of copying data from a cell (e.g. A1) on Sheet1, which changes frequently, to a column (e.g. A:) on Sheet2.
This works fine for the first 263 iterations (it is always 263 regardless of the time intervals), but then on the 264th, instead of copying the next value to the next empty cell in the column, it continuously overwrites the value in cell A2. This is unfortunate, as I need to record at least 600 values.
I am using Excel 2013 under Windows 10.
Should be:
Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = Sheets("Sheet1").Range("A1").Value
Fetching Cells(Rows.Count) with only one parameter does not lead you to the bottom cell of column A, because Cells() will then count items horizontally before moving to next row. After some operations you are falling back to the already used area.

VBA to insert and increment formulae in cell

I have this VBA
Sub ApplyCV()
Range("H2:H5000").Formula = "=GetPattern($A2)"
End Sub
Which basically applies the custom function "=GetPattern" to execute the macro of the same name. This works fine.
However, instead of explicitly stating the range (which will vary with each dataset) I'd like to increment the formula on a loop UNTIL the last row of data or until there is no cell value in A:whatever.
Any help with this would be gratefully received.
Many thanks
Try finding the last value in column A (looking from the bottom up) and using that cell's row to define the extent of the range in column H that the formula is applied to.
Range("H2:H" & cells(rows.count, 1).end(xlup).row).Formula = "=GetPattern($A2)"

Formula to remain after running macro

I was wondering how I can have a formula stay on column J2:J600. The formula is =R2 and would go all the way down to =R600. I thought I could manually put the formula in but every time I run my macro, the formulas disappear. Is there a way to embed the formula into the column? Thanks.
EDIT
Sub FormatCounsel()
Sheet2.Range("J2").FormulaR1C1 = "=RC[0]"`
Sheet2.Range("J2").AutoFill Destination:=Range("J2:J600"), Type:=xlFillDefault
End Sub
This is what I put in and I'm getting an error.
EDIT 2
Sorry I just realized that I want the formula =R2 in cells J2:J600. Sorry if I caused any confusion.
I see a big red flag in your code: you're using circular referencing! This means that you're saying J2 = J2. In other words, your formula refers to itself for a value, so it calculates to find the value, but to find the value it needs to calculate, etc...
Entering circular referencing should always give you an error when you manually enter circular referencing. However, when using VBA to enter the CR, I was only able to raise an error by setting Application.Calculation to xlCalculationManual, and then calculating the sheet.
You may have just made a typo, and that explains why there's circular referencing in your code, but I figured I'd explain it anyway. :)
R1C1 formulas use relative references to refer to cells. So when you say RC[0], you're saying that you want to use the cell in the same row and the same column. Let's see some examples. In our example, the formula will be in B2.
Dim r As Range
Set r = Range("B2")
r = "=RC" '<~~~ the equivalent to what you used in your code. Refers to B2.
r = "=R[-1]C" '<~~~ Refers to B1 (current row minus 1).
r = "=RC[1]" '<~~~ Refers to C2 (current column plus 1).
r = "=R[1]C[1]" '<~~~ Refers to C3 (current row and current column plus 1).
r = "=R[-1]C[-1]" '<~~~ Refers to A1 (current row and current column minus 1).
Now, as far as entering formulas into cells, it can be done all at once and very easily. Consider the example below:
Sub FormatCounsel()
Sheet2.Range("J2:J600") = "=RC[1]" '<~~ Each cell will refer to the cell to the right.
End Sub
Any time you write something else to those cells or clear them with the macro, you will lose those formulas. You need to find the place in your code where you are overwriting or clearing them, and modify that code. The other option is writing those formulas back to the cells at the end of the macro. You can accomplish this with:
Range("J2").FormulaR1C1 = "=RC[0]"
Range("J2").AutoFill Destination:=Range("J2:J600"), Type:=xlFillDefault

Solver Looping Issues in VBA

I am having difficulty with solver. I have tried to develop a for-loop that would call solver many times but I am having issues. I have already added the reference of solver to the workbook from tools/references. I have successfully gotten the loop to work with the solver; unfortunately, solver won't change my input cells automatically. I felt that this issue could be resolved by the SolverReset function but every time I use it it fails, and the loop can no longer find a solution without manually re-solving the system. My code is as follows.
Sub Go_Click()
'Variable Types
Dim x As Double
Dim First_Variable As Range
Dim Second_Variable As Range
Dim Number_of_Calculations As Double
Dim Input_Cells As Range
Dim First_Dimension_Lower As Double
Dim y As Double
Number_of_Calculations = 6
x = (First_Dimension_Upper_Bound - First_Dimension_Lower_Bound) / Number_of_Calculations
For y = 1 To Number_of_Calculations
' x is the integer that the first dimension of the solve will increase by.
' by finding the difference between the upper and lower bound and dividing by the number of calculations
' then the rest is just a for loop, adding the value "x" to each loop
SolverOk SetCell:="First_Dimension", _
MaxMinVal:=3, _
ValueOf:=First_Dimension_Lower_Bound, _
ByChange:="Input_Cells", _
Engine:=1, EngineDesc:="GRG Nonlinear"
SolverSolve
'Just to test the results
MsgBox (Range("b4"))
'increase in the lower first dimension bound
First_Dimension_Lower_Bound = First_Dimension_Lower_Bound + x
Next y
End Sub
Check the return result of SolverSolve to discover if it completed successfully:
If a Solver problem has not been completely defined, SolverSolve
returns the #N/A error value. Otherwise the Solver runs, and
SolverSolve returns an integer value corresponding to the message that
appears in the Solver Results dialog box.
The linked page lists the possible integer values that are returned. For example, 5 indicates "Solver could not find a feasible solution".
You can also supply a Function name as the ShowRef argument to SolverSolve:
SolverSolve(UserFinish, ShowRef)
This Function will be called if Solver pauses for one of the reasons listed in the linked page. For example, 2 means:
Function called because the Max Time limit in the Solver Options
dialog box was exceeded.