triangular pyramid, trigonal pyramid offset-3d-Plane-Intersection By vbasolver - vba

triangular pyramid, trigonal pyramid offset-3d-Plane-Intersection By vbasolver
x=0.250 y=0.250 z=0.250 Inscribed sphere Center
each plane offset 0.25 I challenge vba solver
why ALL-Row 0.250 0.250 0.250
I want ALL-Row 0.250 0.250 0.250
why 6row 8row error
The result is strange
Please tell me how to fix it.
Const x0 = 0
Const y0 = 0
Const z0 = 2
Const x1 = 0
Const y1 = 0
Const z1 = 0
Const x2 = 1
Const y2 = 0
Const z2 = 0
Const x3 = 0
Const y3 = 1
Const z3 = 0
Const r0 = 0.25
Const r1 = 0.25
Const r2 = 0.25
Const r3 = 0.25
Function myR1C1toA1(i, j)
myR1C1toA1 = Application.ConvertFormula("R" & i & "C" & j, xlR1C1, xlA1)
End Function
Function myPlane(Ax, Ay, Az, Bx, By, Bz, Cx, Cy, Cz)
a = (By - Ay) * (Cz - Az) - (Cy - Ay) * (Bz - Az)
b = (Bz - Az) * (Cx - Ax) - (Cz - Az) * (Bx - Ax)
c = (Bx - Ax) * (Cy - Ay) - (Cx - Ax) * (By - Ay)
d = -(a * Ax + b * Ay + c * Az)
myPlane = Array(a, b, c, d)
End Function
Function myOffset3PlaneIntersection(irow, x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3, r1, r2, r3)
Dim v1 As Variant
Dim v2 As Variant
Dim v3 As Variant
'
v1 = myPlane(x0, y0, z0, x2, y2, z2, x3, y3, z3)
v2 = myPlane(x0, y0, z0, x3, y3, z3, x1, y1, z1)
v3 = myPlane(x0, y0, z0, x1, y1, z1, x2, y2, z2)
'
my1 = "(Abs(" & v1(0) & " * " & myR1C1toA1(irow, 1) & "+ " & v1(1) & " * " & myR1C1toA1(irow, 2) & "+ " & v1(2) & " * " & myR1C1toA1(irow, 3) & "+ " & v1(3) & ") / Sqrt(" & v1(0) & " ^ 2 + " & v1(1) & " ^ 2 +" & v1(2) & " ^ 2) - " & myR1C1toA1(irow, 1) & ")"
my2 = "(Abs(" & v2(0) & " * " & myR1C1toA1(irow, 1) & "+ " & v2(1) & " * " & myR1C1toA1(irow, 2) & "+ " & v2(2) & " * " & myR1C1toA1(irow, 3) & "+ " & v2(3) & ") / Sqrt(" & v2(0) & " ^ 2 + " & v2(1) & " ^ 2 +" & v2(2) & " ^ 2) - " & myR1C1toA1(irow, 2) & ")"
my3 = "(Abs(" & v3(0) & " * " & myR1C1toA1(irow, 1) & "+ " & v3(1) & " * " & myR1C1toA1(irow, 2) & "+ " & v3(2) & " * " & myR1C1toA1(irow, 3) & "+ " & v3(3) & ") / Sqrt(" & v3(0) & " ^ 2 + " & v3(1) & " ^ 2 +" & v3(2) & " ^ 2) - " & myR1C1toA1(irow, 3) & ")"
Range(myR1C1toA1(irow, 5)).Formula = "=" & my1 & "^ 2 +" & my2 & "^ 2 +" & my3 & "^ 2"
'
Dim ws As Worksheet: Set ws = ActiveSheet
SolverReset
SolverOk setCell:=ws.Range(myR1C1toA1(irow, 5)), _
MaxMinVal:=3, _
ByChange:=ws.Range(myR1C1toA1(irow, 1) & ":" & myR1C1toA1(irow, 3)), _
EngineDesc:="GRG Nonlinear"
SolverSolve UserFinish:=True
End Function
Sub myFormat()
Columns("A:E").Select
Selection.NumberFormatLocal = "0.000_ "
Range("A5").Select
End Sub
Sub aaa_Main()
Dim myXYZ As Variant
ActiveSheet.Cells.Clear
MsgBox "Solver Start"
Cells(1, 1) = x0
Cells(1, 2) = y0
Cells(1, 3) = z0
Cells(2, 1) = x1
Cells(2, 2) = y1
Cells(2, 3) = z1
Cells(3, 1) = x2
Cells(3, 2) = y2
Cells(3, 3) = z2
Cells(4, 1) = x3
Cells(4, 2) = y3
Cells(4, 3) = z3
'-----------------------------------------------------------------------------------------------------
irow = 5
Cells(irow + 0, 4) = r0
Cells(irow + 1, 4) = r1
Cells(irow + 2, 4) = r2
Cells(irow + 3, 4) = r3
myXYZ = myOffset3PlaneIntersection(irow + 0, x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3, r1, r2, r3)
myXYZ = myOffset3PlaneIntersection(irow + 1, x1, y1, z1, x2, y2, z2, x3, y3, z3, x0, y0, z0, r2, r3, r0)
myXYZ = myOffset3PlaneIntersection(irow + 2, x2, y2, z2, x3, y3, z3, x0, y0, z0, x1, y1, z1, r3, r0, r1)
myXYZ = myOffset3PlaneIntersection(irow + 3, x3, y3, z3, x0, y0, z0, x1, y1, z1, x2, y2, z2, r0, r1, r2)
myFormat
End Sub
'1 0.000 0.000 2.000
'2 0.000 0.000 0.000
'3 1.000 0.000 0.000
'4 0.000 1.000 0.000
'5 0.250 0.250 0.250 0.250 0.000
'6 0.000 0.000 0.000 0.250 0.000 ???? I want 0.250 0.250 0.250
'7 0.250 0.250 0.250 0.250 0.000
'8 0.102 0.339 0.102 0.250 0.000 ???? I want 0.250 0.250 0.250
(2021-11-15)I try sympy
from sympy import *
def myVol(PTO,PTA,PTB,PTC):
return Matrix([[PTA.x-PTO.x, PTA.y-PTO.y, PTA.z-PTO.z], [PTB.x-PTO.x, PTB.y-PTO.y, PTB.z-PTO.z], [PTC.x-PTO.x, PTC.y-PTO.y, PTC.z-PTO.z]]).det()/6
def myUnitVector(myPoint3D):
myL=myPoint3D.distance((0, 0))
return Point3D(myPoint3D.x/myL,myPoint3D.y/myL,myPoint3D.z/myL)
def myHtoP(myHairetu):
return Point3D(myHairetu[0],myHairetu[1],myHairetu[2])
def my3PLaneIntersection(PTO,PTA,PTB,PTC,RA,RB,RC):
vA =myUnitVector(myHtoP(Plane(PTO, PTB, PTC).normal_vector))
PLA=Plane(PTO + RA * vA, normal_vector=vA)
vB =myUnitVector(myHtoP(Plane(PTO, PTC, PTA).normal_vector))
PLB=Plane(PTO + RB * vB, normal_vector=vB)
vC =myUnitVector(myHtoP(Plane(PTO, PTA, PTB).normal_vector))
PLC=Plane(PTO + RC * vC, normal_vector=vC)
return PLC.intersection(PLB.intersection(PLA)[0])
PTO,PTA,PTB,PTC=Point3D(0,0,0),Point3D(1,0,0),Point3D(0,1,0),Point3D(0,0,2)
print("#",myVol(PTO,PTA,PTB,PTC))
myRO,myRA,myRB,myRC=0,0,0,0
print("#",myVol(
my3PLaneIntersection(PTO,PTA,PTB,PTC,myRO,myRO,myRO)[0],
my3PLaneIntersection(PTA,PTC,PTB,PTO,myRA,myRA,myRA)[0],
my3PLaneIntersection(PTB,PTC,PTO,PTA,myRB,myRB,myRB)[0],
my3PLaneIntersection(PTC,PTB,PTA,PTO,myRC,myRC,myRC)[0]))
myRO,myRA,myRB,myRC=1/4,1/4,1/4,1/4
print("#",myVol(
my3PLaneIntersection(PTO,PTA,PTB,PTC,myRO,myRO,myRO)[0],
my3PLaneIntersection(PTA,PTC,PTB,PTO,myRA,myRA,myRA)[0],
my3PLaneIntersection(PTB,PTC,PTO,PTA,myRB,myRB,myRB)[0],
my3PLaneIntersection(PTC,PTB,PTA,PTO,myRC,myRC,myRC)[0]))
myRO,myRA,myRB,myRC=-1/4,-1/4,-1/4,-1/4
print("#",myVol(
my3PLaneIntersection(PTO,PTA,PTB,PTC,myRO,myRO,myRO)[0],
my3PLaneIntersection(PTA,PTC,PTB,PTO,myRA,myRA,myRA)[0],
my3PLaneIntersection(PTB,PTC,PTO,PTA,myRB,myRB,myRB)[0],
my3PLaneIntersection(PTC,PTB,PTA,PTO,myRC,myRC,myRC)[0]))
# 1/3
# 1/3
# 0
# 8/3

I check
from sympy import *
var('m')
def myUnitVector(myPoint3D):
myL=myPoint3D.distance((0, 0))
return Point3D(myPoint3D.x/myL,myPoint3D.y/myL,myPoint3D.z/myL)
def myHtoP(myHairetu):
return Point3D(myHairetu[0],myHairetu[1],myHairetu[2])
def my3PLaneIntersection(PTO,PTA,PTB,PTC,RA,RB,RC):
vA =myUnitVector(myHtoP(Plane(PTO, PTB, PTC).normal_vector))
PLA=Plane(PTO + RA * vA, normal_vector=vA)
vB =myUnitVector(myHtoP(Plane(PTO, PTC, PTA).normal_vector))
PLB=Plane(PTO + RB * vB, normal_vector=vB)
vC =myUnitVector(myHtoP(Plane(PTO, PTA, PTB).normal_vector))
PLC=Plane(PTO + RC * vC, normal_vector=vC)
return PLC.intersection(PLB.intersection(PLA)[0])
def myProjection(PTO,PTA,PTC,PTOO):
v = myUnitVector(myHtoP(Plane(PTO, PTA, PTC).normal_vector))
return solve(PTOO - Plane(PTO, PTA, PTC).projection(PTOO) - m * v, m)[m] * (-1)
PTO,PTA,PTB,PTC=Point3D(0,0,0),Point3D(1,0,0),Point3D(0,1,0),Point3D(0,0,2)
myRO,myRA,myRB,myRC=-1/4,-1/4,-1/4,-1/4
PTOO= my3PLaneIntersection(PTO, PTA,PTB,PTC,myRO,myRO,myRO)[0]
PTAA= my3PLaneIntersection(PTA, PTC,PTB,PTO,myRA,myRA,myRA)[0]
PTBB= my3PLaneIntersection(PTB, PTC,PTO,PTA,myRB,myRB,myRB)[0]
PTCC= my3PLaneIntersection(PTC, PTB,PTA,PTO,myRC,myRC,myRC)[0]
print("#",PTOO,"\n#",PTAA,"\n#",PTBB,"\n#",PTCC,)
print("#",myProjection(PTO,PTB,PTA,PTOO),
myProjection(PTO,PTA,PTC,PTOO),
myProjection(PTO,PTC,PTB,PTOO))
print("#",myProjection(PTA,PTO,PTB,PTAA),
myProjection(PTA,PTC,PTO,PTAA),
myProjection(PTA,PTB,PTC,PTAA))
print("#",myProjection(PTB,PTA,PTO,PTBB),
myProjection(PTB,PTO,PTC,PTBB),
myProjection(PTB,PTC,PTA,PTBB))
print("#",myProjection(PTC,PTO,PTA,PTCC),
myProjection(PTC,PTB,PTO,PTCC),
myProjection(PTC,PTA,PTB,PTCC))
# Point3D(-1/4, -1/4, -1/4)
# Point3D(7/4, -1/4, -1/4)
# Point3D(-1/4, 7/4, -1/4)
# Point3D(-1/4, -1/4, 15/4)
# -1/4 -1/4 -1/4
# -1/4 -1/4 -1/4
# -1/4 -1/4 -1/4
# -1/4 -1/4 -1/4

Related

Is there a faster alternative for DLookup to fill unbound text fields on a form?

I'm using DLookup to search for a field in a table. It runs correctly, but is slow. Is there anything I can do to speed it up?
Here's my existing code:
Me(k1) = Dlookup("[KLant]", "[Planning_tbl02]", "[Plek#]=" & p & " AND [datum]='" & Me(k4) & "'" & " AND [bezet_ochtend]='" & "bezet" & "'")
Add indexes in the table on the fields you filter on.
thanks for your replys.
It's a form with +/- 780 unbound textfields which should be filled with data from a table.
I build a program for a little camping and this form is a sort of planning for the available places per day. So they have 30 places and they want to see 2 weeks, so a lot of fields, because they aslo want the day split in morning and and afternoon.
I know, it's maybe not the correct way to progam, but my knowledge is not bigger at the moment :-(
So, if somebody has a good suggestion, I will really appreciate that.
See below for the complete code, it's a loop in a loop.
Private Sub Form_Load()
For p = 1 To 30
k2 = 1
k3 = 1
r1 = r1 - 49
g = g + 52
b = b - 127
If r1 < 0 Then r1 = 255
If g < 0 Then g = 200
If b < 0 Then b = 160
If r1 > 255 Then r1 = 31
If g > 255 Then g = 100
If b > 255 Then b = 56
For k2 = 1 To 26
k1 = "pl" & p & "_" & k2
k4 = "calday" & k3
If r1 < 0 Then r1 = 255
If g < 0 Then g = 200
If b < 0 Then b = 160
If r1 > 255 Then r1 = 31
If g > 255 Then g = 100
If b > 255 Then b = 56
If k2 Mod 2 = 1 Then
Dim strCriteria As String, strQuery As String
strCriteria = _
BuildCriteria("[Plek#]", dbLong, p) & " And " & _
BuildCriteria("[datum]", dbDate, Me(k4)) & " And " & _
BuildCriteria("[bezet_ochtend]", dbText, """bezet""")
strQuery = "SELECT [KLant] FROM [Planning_tbl02] WHERE " & strCriteria
With CurrentDb.OpenRecordset(strQuery, dbOpenForwardOnly)
If Not .EOF Then
Me(k1) = ![klant]
Else
Me(k1) = Null
End If
.Close
End With
If k2 = 1 Then
If Me(k1).Value <> "" Then
Me(k1).BackColor = RGB(r1, g, b)
End If
End If
If k2 - 1 > 0 Then
If Me(k1).Value <> "" And IsNull(Me("pl" & p & "_" & (k2 - 1)).Value) Then
Me(k1).BackColor = RGB(r1, g, b)
End If
End If
If k2 - 1 > 0 Then
If Me(k1).Value <> "" And Me("pl" & p & "_" & k2) = Me("pl" & p & "_" & (k2 - 1))Then
Me(k1).BackColor = RGB(r1, g, b)
End If
End If
If k2 - 1 > 0 Then
If Me("pl" & p & "_" & k2) <> Me("pl" & p & "_" & (k2 - 1)) Then
r1 = r1 - 49
g = g + 52
b = b - 127
Me(k1).BackColor = RGB(r1, g, b)
End If
End If
End If
If k2 Mod 2 <> 1 Then
strCriteria = _
BuildCriteria("[Plek#]", dbLong, p) & " And " & _
BuildCriteria("[datum]", dbDate, Me(k4)) & " And " & _
BuildCriteria("[bezet_ochtend]", dbText, """bezet""")
strQuery = "SELECT [KLant] FROM [Planning_tbl02] WHERE " & strCriteria
With CurrentDb.OpenRecordset(strQuery, dbOpenForwardOnly)
If Not .EOF Then
Me(k1) = ![klant]
Else
Me(k1) = Null
End If
.Close
End With
If Me(k1).Value <> "" And IsNull(Me("pl" & p & "_" & (k2 - 1)).Value) Then
Me(k1).BackColor = RGB(r1, g, b)
End If
If Me(k1).Value <> "" And Me("pl" & p & "_" & k2) = Me("pl" & p & "_" & (k2 - 1))Then
Me(k1).BackColor = RGB(r1, g, b)
End If
If k2 - 1 > 0 Then
If Me(k1).Value <> "" And Me("pl" & p & "_" & k2) <> Me("pl" & p & "_" & (k2 - 1)) Then
Me(k1).BackColor = RGB(r1, g, b)
End If
End If
If k2 - 1 > 0 Then
If Me("pl" & p & "_" & k2) <> Me("pl" & p & "_" & (k2 - 1)) Then
r1 = r1 - 49
g = g + 52
b = b - 127
If r1 < 0 Then r1 = 255
If g < 0 Then g = 200
If b < 0 Then b = 160
Me(k1).BackColor = RGB(r1, g, b)
End If
End If
End If
If k2 Mod 2 <> 1 Then
k3 = k3 + 1
End If
Next
Next
End Sub
You could write your own lookup code that opens a recordset and finds the desired value, for example:
Dim strCriteria As String, strQuery As String
strCriteria = _
BuildCriteria("[Plek#]", dbLong, p) & " And " & _
BuildCriteria("[datum]", dbDate, Me(k4)) & " And " & _
BuildCriteria("[bezet_ochtend]", dbText, """bezet""")
strQuery = "SELECT [KLant] FROM [Planning_tbl02] WHERE " & strCriteria
With CurrentDb.OpenRecordset(strQuery, dbOpenForwardOnly)
If Not .EOF Then
Me(k1) = ![KLant]
Else
Me(k1) = Null
End If
.Close
End With
Added:
After reviewing your code, I found that the statements for odd and even values of k2 doesn't differ much, so I was able to simplify the code a little. Also, I found that k4 changes only for odd values of k2 which halves the number of database searches. This means of course, that there will be no difference in the afternoon. Finally, as promised in my comment, I reduced the number of recordsets to 30 and implemented searches with FindFirst for the dates. Here's my result:
Private Sub Form_Load()
Dim p As Integer, k2 As Integer
Dim k1 As String, k1_prev As String, k4 As String
Dim r1 As Integer, g As Integer, b As Integer
Dim strCriteria As String, strQuery As String
For p = 1 To 30
If r1 < 49 Then r1 = 255 Else r1 = r1 - 49
If g > 203 Then g = 100 Else g = g + 52
If b < 127 Then b = 160 Else b = b - 127
strQuery = "SELECT [KLant], [datum] FROM [Planning_tbl02] WHERE " & _
BuildCriteria("[Plek#]", dbLong, p) & " And " & _
BuildCriteria("[bezet_ochtend]", dbText, """bezet""")
With CurrentDb.OpenRecordset(strQuery, dbOpenDynaset)
For k2 = 1 To 26
k1_prev = k1
k1 = "pl" & p & "_" & k2
If k2 Mod 2 = 1 Then
k4 = "calday" & (k2 + 1) \ 2
.FindFirst BuildCriteria("[datum]", dbDate, Me(k4))
If .NoMatch Then Me(k1) = Null Else Me(k1) = ![klant]
Else
Me(k1) = Me(k1_prev)
End If
If Not IsNull(Me(k1)) Then
If k2 = 1 Then
Me(k1).BackColor = RGB(r1, g, b)
Else
If Me(k1) <> Me(k1_prev) Then 'next color
If r1 < 49 Then r1 = 255 Else r1 = r1 - 49
If g > 203 Then g = 100 Else g = g + 52
If b < 127 Then b = 160 Else b = b - 127
End If
Me(k1).BackColor = RGB(r1, g, b)
End If
End If
Next
.Close
End With
Next
End Sub

Why does my script multiply values by 30.48?

My AutoIt script has users paste text into a field, then click a button to convert the customary units into metric units. It converts not only words, but the numbers preceding them as well.
The text below is the input:
1 foot 1 inch
2 feet 2 inches
3 feet 3 inches
1 inch
2 inches
3 in
1 foot
2 feet
3 ft
This is the expected output:
33.02 centimeters
66.04 centimeters
99.06 centimeters
2.54 centimeters
5.08 centimeters
7.62 cm
30.48 centimeters
60.96 centimeters
91.44 cm
But this is what I get:
1006.4496 centimeters
2012.8992 centimeters
3019.3488 centimeters
2.54 centimeters
5.08 centimeters
7.62 cm
30.48 centimeters
60.96 centimeters
91.44 centimeters
Seems first three lines are multiplied by 30.48. I do not want that. Here is the code:
Case $msg = $CTRL_i
;For unit measurements of feet and inches
$input_str = GUICtrlRead($Textbox)
$WordArray = StringRegExp($input_str, "[\s\.:;,]*([a-zA-Z0-9-_]*\.?[a-zA-Z0-9-_]+)[\s\.:;,]*", 3)
;MsgBox($MB_OK, "Size:", UBound($WordArray))
For $i = 0 To (UBound($WordArray) - 1) Step 1
If (($i + 3) <= UBound($WordArray)) Then
If (StringIsDigit($WordArray[$i]) Or StringIsFloat($WordArray[$i])) And ($WordArray[$i + 1] = "feet" Or "foot" Or "ft") And (StringIsDigit($WordArray[$i + 2]) Or StringIsFloat($WordArray[$i + 2])) And ($WordArray[$i + 3] = "inches" Or "inch" Or "in") Then
$cm_value = ($WordArray[$i] * 30.48) + ($WordArray[$i + 2] * 2.54)
$old_string = $WordArray[$i] & " " & $WordArray[$i + 1] & " " & $WordArray[$i + 2] & " " & $WordArray[$i + 3]
$new_string = $cm_value & " centimeters"
$input_str = StringReplace($input_str, $old_string, $new_string, 1)
MsgBox($MB_OK, "Feet and inches", $WordArray[$i])
EndIf
EndIf
Next
$WordArray = StringRegExp($input_str, "[\s\.:;,]*([a-zA-Z0-9-_]*\.?[a-zA-Z0-9-_]+)[\s\.:;,]*", 3)
;MsgBox($MB_OK, "Size:", UBound($WordArray))
For $i = 0 To (UBound($WordArray) - 1) Step 1
If (($i + 1) <= UBound($WordArray)) Then
;This is for when a measurement of inches is represented as plural.
If (StringIsDigit($WordArray[$i]) Or StringIsFloat($WordArray[$i])) And $WordArray[$i + 1] = "inches" Then
$cm_value = $WordArray[$i] * 2.54
$old_string = $WordArray[$i] & " " & $WordArray[$i + 1]
$new_string = $cm_value & " centimeters"
$input_str = StringReplace($input_str, $old_string, $new_string, 1)
MsgBox($MB_OK, "inches", $WordArray[$i])
;This is for when a measurement of inches is represented as singular.
ElseIf (StringIsDigit($WordArray[$i]) Or StringIsFloat($WordArray[$i])) And $WordArray[$i + 1] = "inch" Then
$cm_value = $WordArray[$i] * 2.54
$old_string = $WordArray[$i] & " " & $WordArray[$i + 1]
$new_string = $cm_value & " centimeters"
$input_str = StringReplace($input_str, $old_string, $new_string, 1)
MsgBox($MB_OK, "inch", $WordArray[$i])
;This is for when a measurement of inches is represented as an abbreviation.
ElseIf (StringIsDigit($WordArray[$i]) Or StringIsFloat($WordArray[$i])) And $WordArray[$i + 1] = "in" Then
$cm_value = $WordArray[$i] * 2.54
$old_string = $WordArray[$i] & " " & $WordArray[$i + 1]
$new_string = $cm_value & " cm"
$input_str = StringReplace($input_str, $old_string, $new_string, 1)
MsgBox($MB_OK, "in", $WordArray[$i])
EndIf
EndIf
Next
$WordArrayC = StringRegExp($input_str, "[\s\.:;,]*([a-zA-Z0-9-_]*\.?[a-zA-Z0-9-_]+)[\s\.:;,]*", 3)
;MsgBox($MB_OK, "Size:", UBound($WordArray))
For $i = 0 To (UBound($WordArray) - 1) Step 1
If (($i + 1) <= UBound($WordArray)) Then
;This is for when a measurement of feet is represented as plural or singular.
If (StringIsDigit($WordArray[$i]) Or StringIsFloat($WordArray[$i])) And ($WordArray[$i + 1] = "feet" Or "foot") Then
$cm_value = $WordArray[$i] * 30.48
$old_string = $WordArray[$i] & " " & $WordArray[$i + 1]
$new_string = $cm_value & " centimeters"
$input_str = StringReplace($input_str, $old_string, $new_string, 1)
MsgBox($MB_OK, "feet", $WordArray[$i])
;This is for when a measurement of feet is represented as an abbreviation.
ElseIf (StringIsDigit($WordArray[$i]) Or StringIsFloat($WordArray[$i])) And $WordArray[$i + 1] = "ft" Then
$cm_value = $WordArray[$i] * 30.48
$old_string = $WordArray[$i] & " " & $WordArrayC[$i + 1]
$new_string = $cm_value & " cm"
$input_str = StringReplace($input_str, $old_string, $new_string, 1)
MsgBox($MB_OK, "ft", $WordArray[$i])
EndIf
EndIf
Next
GUICtrlSetData($Textbox, $input_str)
This kind of syntax:
($WordArray[$i+1] = "feet" Or "foot" Or "ft")
is actually interpreted as
(($WordArray[$i+1] = "feet") Or ("foot") Or ("ft"))
which "foot" is always True and "ft" is always True as neither are empty strings.
Use instead this syntax:
($WordArray[$i+1] = "feet" Or $WordArray[$i+1] = "foot" Or $WordArray[$i+1] = "ft")
The later compares $WordArray[$i+1] with each string.
Change all instances of that kind of syntax and your code may work as expected.
this is a little bit error-prone, but it shows an easier way.
#include <Array.au3>
$str = "1 foot 1 inch" & #CR & _
"2 feet 2 inches" & #CR & _
"3 feet 3 inches" & #CR & _
"1 inch" & #CR & _
"2 inches" & #CR & _
"3 in" & #CR & _
"2 feet" & #CR & _
"1 foot" & #CR & _
"3 ft"
$rows_A = StringSplit($str, #CR, 2)
;~ _ArrayDisplay($rows_A, 'Rows')
;~ 33.02 centimeters
;~ 66.04 centimeters
;~ 99.06 centimeters
;~ 2.54 centimeters
;~ 5.08 centimeters
;~ 7.62 centimeters
;~ 30.48 centimeters
;~ 60.96 centimeters
;~ 91.44 centimeters
Local $sum = 0
For $i = 0 To UBound($rows_A) - 1
If StringRegExp($rows_A[$i], '(\d.*?\d.*?)', 0) Then
$splitted_row_A = StringRegExp($rows_A[$i], '(\d)\s*(\w+)', 3)
;~ _ArrayDisplay($splitted_row_A)
$sum = 0
For $y = 0 To UBound($splitted_row_A) - 2
If StringInStr($splitted_row_A[$y + 1], 'in') Then
$sum += $splitted_row_A[$y] * 2.54
ElseIf StringInStr($splitted_row_A[$y + 1], 'f') Then
$sum += $splitted_row_A[$y] * 30.48
EndIf
Next
If $sum > 0 Then ConsoleWrite($rows_A[$i] & ' => ' & $sum & #CRLF)
Else
If StringInStr($rows_A[$i], 'in') Then ConsoleWrite($rows_A[$i] & ' = ' & $rows_A[$i] * 2.54 & #CRLF)
If StringInStr($rows_A[$i], 'f') Then ConsoleWrite($rows_A[$i] & ' = ' & $rows_A[$i] * 30.48 & #CRLF)
EndIf
Next

VBA nested looping with do until loop

I need a looping structure that checks a range of cells, then if the cell and a cell that is in the range equal each other then the font should turn red. My problem is that my do until loop won't get entered. This is what I have right now.
`
Dim finalrow As Long
finalrow = Worksheets("Redundancy").Cells(Worksheets("Redundancy").Rows.Count, "D").End(xlUp).Row
Dim z As Long
Dim w As Long
Dim r As Long
w = 2
r = 0
For z = 2 To finalrow
If Range("L" & z) = Range("L" & z + 1) & Range("J" & z) <> Range("J" & z + 1) Then
Do Until Range("L" & z) = Range("L" & z + 1) & Range("J" & z) <> Range("J" & z + 1)
If Cells(w, 4) = Cells(z + 1, 4 + r) Then
Cells(w, 1).Font.ColorIndex = 3
Cells(z + 1, 1).Font.ColorIndex = 3
If r = 4 Then
w = w + 1
End If
End If
r = r + 1
Loop
End If
Next z
`
I changed it to this, but it exits the loop all together right when it is about to enter the do while loop.
`
For z = 2 To finalrow
Do While (Range("L" & z) = Range("L" & z + 1) And Range("J" & z) <> Range("J" & z + 1))
If Cells(w, 4) = Cells(z + 1, 4 + r) Then
Cells(w, 1).Font.ColorIndex = 3
Cells(z + 1, 1).Font.ColorIndex = 3
If r = 4 Then
w = w + 1
End If
End If
r = r + 1
Loop
Next z
`
If you do this;
Range("L" & z) = Range("L" & z + 1) and Range("J" & z) <> Range("J" & z + 1)
you are comparing Range objects. What you instead want to do is to compare the values in those range objects. So use this instead;
Range("L" & z).value = Range("L" & z + 1).value and Range("J" & z).value <> Range("J" & z + 1).value
However when you use the cells(row,column) you don't have this problem.
I am curious though, was it not possible to use conditional formatting instead?
Use the 'and' operator instead of '&'.

Run Time Error '1004', have researched and tried several recommended solutions to no avail

I am trying to fill a range with a formula and continue to get a runtime error '1004'. The error occurs at the line I have starred Sheets("Forecast").Range("H125").Formula = formulaTest. The code in my Sub is as follows:
Sub FirmShareFill()
Dim RampUp As Range
Dim RampBas As Range
Dim RampDn As Range
Dim Numbering As Range
Dim Approval As Range
Dim PeakShare As Range
Dim tcount As Byte
Dim bcount As Byte
Dim ubdcount As Byte
Dim yearRange2 As Byte
year = Worksheets("Inputs").Range("B6").Value
cntry = Worksheets("Inputs").Range("B5").Value
bnd = Worksheets("Inputs").Range("B3").Value
typ = Worksheets("Inputs").Range("B2").Value
cat = Worksheets("Inputs").Range("B4").Value
tcount = bnd * cat + bnd
ubdcount = tcount * 2 + 1
yearCount = year * 4 - 1
For ubd = 1 To 3
For t = 1 To typ
For b = 1 To bnd
For c = 1 To cat
For i = 1 To cntry
Set RampUp = Columns(7).Find(What:="Ramp_Up" & i, MatchCase:=True).Offset(0, 1)
Set RampBas = Columns(7).Find(What:="Ramp_Bas" & i, MatchCase:=True).Offset(0, 1)
Set RampDn = Columns(7).Find(What:="Ramp_Dn" & i, MatchCase:=True).Offset(0, 1)
Set Numbering = Sheets("Inputs").Range("B13")
Set Approval = Columns(6).Find(What:="Approval", MatchCase:=True).Offset(i, 2 + ubd)
bcount = c + (cat + 1) * (b - 1)
If t = 1 And b = 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share", MatchCase:=True).Offset(4 + i, c)
ElseIf t = 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, bcount)
ElseIf t > 1 And b = 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, c + tcount)
ElseIf t > 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, tcount + bcount)
ElseIf t = 1 And b = 1 And ubd = 2 Then
Set PeakShare = Columns(5).Find(What:="Peak Share", MatchCase:=True).Offset(4 + i, c + ubdcount)
ElseIf t = 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, bcount + ubdcount)
ElseIf t > 1 And b = 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, c + tcount + ubdcount)
ElseIf t > 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, tcount + bcount + ubdcount)
ElseIf t = 1 And b = 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share", MatchCase:=True).Offset(4 + i, c + 2 * ubdcount)
ElseIf t = 1 And b > 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, bcount + 2 * ubdcount)
ElseIf t > 1 And b = 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, c + tcount + 2 * ubdcount)
ElseIf t > 1 And b > 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, tcount + bcount + 2 * ubdcount)
End If
Dim formulaTest As String
formulaTest = "=IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ","", " & PeakShare.Address & " * " & RampUp.Address & ")"
If ubd = 1 Then
**Sheets("Forecast").Range("H125").Formula = formulaTest**
ActiveCell.Offset(1, 0).Select
ElseIf ubd = 2 Then
Range(ActiveCell, ActiveCell.Offset(0, yearRange2)).Formula = "=IF(" & Numbering.Address(False, False) & " < " & Approval.Offset(1, 0).Address & ","", " & PeakShare.Address & " * " & RampBas.Address & ""
ElseIf ubd = 3 Then
Range(ActiveCell, ActiveCell.Offset(0, yearRange2)).Formula = "=IF(" & Numbering.Address(False, False) & " < " & Approval.Offset(1, 0).Address & ","", " & PeakShare.Address & " * " & RampDn.Address & ""
End If
Next i
ActiveCell.Offset(1, 0).Select
Next c
Next b
Next t
Next ubd
End Sub
I believe the error may have something to do with how I declared the range "numbering" range, but as of yet I have been unable to figure it out. I have used this code on the same sheet many times, the only difference being that I have set a range, numbering, on a different sheet.
This should work:
formulaTest = "=IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ",""""," & PeakShare.Address & "*" & RampUp.Address & ")"
As #Comintern pointed out, you need to use """" to include double empty speech marks in your formula. I also removed the spaces either side of the *
change
IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ","", " & PeakShare.Address & " * " & RampUp.Address & ")"
to
IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ","""", " & PeakShare.Address & " * " & RampUp.Address & ")"
Instead of counting how many " you have, you can use Chr(34) inside " to have a Formula check for ".
In your case, use:
"=IF(" & Numbering.Address(False, False) & "<" & Approval.Address & "," & Chr(34) & ", " & PeakShare.Address & " * " & RampUp.Address & ")"

Loop within loops vba

I'm trying to create a spreadsheet that could execute a BDH bloomberg code for each equity and within each equity id want it to go through all of the criteria such as "PX_Last", VOL_90D, PX_BID and etc.
Essentially, the ideal output I'd like would be:
Eg:
0665 HK Equity -> PX_Last, PX_BID, PX_ASK, VOL_90D, then,
1098 HK Equity -> PX_Last, PX_BID, PX_ASK, VOL_90D, then,
etc.
Here is a code that I've recently created for my spreadsheet.
Would appreciate any insights about my code!
For x = 1 To i
If x = 1 Then
equity = Worksheets(1).Cells(x + 2, 2)
Worksheets(2).Cells(2, 2).Value = equity
For y = 1 To j
If y = 1 Then
reutersticker = Worksheets(1).Cells(y + 2, 1)
Worksheets(2).Cells(1, 2).Value = reutersticker
For Z = 1 To k
If Z = 1 Then
LastPrice = Worksheets(1).Cells(Z + 1, 8)
Worksheets(2).Cells(3, 1).FormulaR1C1 = "=BDH(""" & equity & """," & LastPrice & ",""" & StartDate & """,""" & EndDate & """," & Weekdays & "," & Fill & ")"
ElseIf Z > 1 Then
LastPrice = Worksheets(1).Cells(Z + 1, 8)
Worksheets(2).Cells(3, 1).Offset(, (2 * Z) - 2).FormulaR1C1 = "=BDH(""" & equity & """," & LastPrice & ",""" & StartDate & """,""" & EndDate & """," & Weekdays & "," & Fill & ")"
End If
Next Z
ElseIf y > 1 Then
reutersticker = Worksheets(1).Cells(y + 2, 1)
Worksheets(2).Cells(1, 2).Offset(, (4 * y) - 2).Value = reutersticker
End If
Next y
ElseIf x > 1 Then
equity = Worksheets(1).Cells(x + 2, 2)
Worksheets(2).Cells(2, 2).Offset(, (8 * x) - 2).Value = equity
End If
Next x
End Sub