Na přesně toto mám makro, kde vstupem jsou dva parametry (vzdálenost řezné roviny, druhý parametr je objem). Dále se musí definovat počáteční krok prvního z parametrů. Používám toto makro na řezání objemů a funguje i v sestavách, kdy např. potřebuji najít určitou polohu sestavy (např. minimální vzdálenost nějakého dílu od jiného).
Makro nedělá nic jiného než že inkrementuje první z parametrů, provede update a vyhodnotí druhý parametr a toto v cyklu, který je omezen přesností, jakou vyžaduji a omezuji si to i max. počtem kroků, páč někdy zadám špatně vstup. Makro pracuje s parametry a s hodnotovými constrainy.
Pokud hodláte makro komerčně používat, tak Vám mohu zaslat číslo účtu, kam je možno poukázat odměnu za toto makro.
A zde je již ono makro:
Option Explicit
Public oPart As Part
Public oSestava As Product
Public prmVstupniParam As KnowledgewareTypeLib.Parameter
Public prmVystupParam As KnowledgewareTypeLib.Parameter
Public dblZadanaHodnota As Double
Public dblKrok As Double
Public btePresnost As Byte
Public lngMaxPocIter As Long
Public strDokTyp As String
Public blnZadano As Boolean
Sub CATMain()
Dim clsLog As New clsLogFile
clsLog.MakroLog ("Optimalizace")
clsLog.CloseFile
Set clsLog = Nothing
Call InterfaceOptimalizace
Set oPart = Nothing
Set oSestava = Nothing
Set prmVstupniParam = Nothing
Set prmVystupParam = Nothing
End Sub
Sub InterfaceOptimalizace()
Dim MsgText As String
Dim MsgResponse As Long
Dim intOptimVysledek As Integer
blnZadano = False
strDokTyp = ""
Err.Clear
On Error GoTo ErrHandler
If TypeName(CATIA.ActiveDocument) = "PartDocument" Then
Set oPart = CATIA.ActiveDocument.Part
strDokTyp = "Part"
ElseIf TypeName(CATIA.ActiveDocument) = "ProductDocument" Then
Set oSestava = CATIA.ActiveDocument.Product
strDokTyp = "Product"
Else
MsgText = TypeName(CATIA.ActiveDocument) & " is unsupported document!" & vbCrLf
MsgText = MsgText & "CATPart or CATProduct hAs to be active."
MsgResponse = MsgBox(MsgText, vbExclamation)
Exit Sub
End If
Err.Clear
On Error GoTo 0
frmOptimEnter.Show
If blnZadano Then
If strDokTyp = "Part" Then
intOptimVysledek = OptimalizacniFce(oPart, prmVstupniParam, prmVystupParam, _
dblKrok, dblZadanaHodnota, btePresnost, lngMaxPocIter)
ElseIf strDokTyp = "Product" Then
intOptimVysledek = OptimalizacniFceProduct(oSestava, prmVstupniParam, prmVystupParam, _
dblKrok, dblZadanaHodnota, btePresnost, lngMaxPocIter)
Else
intOptimVysledek = -6
End If
CATIA.StatusBar = "Výsledek optimalizace: " & CStr(intOptimVysledek)
Else
CATIA.StatusBar = "Makro pøerušeno"
End If
Exit Sub
ErrHandler:
MsgText = "Unsupported document is active!" & vbCrLf
MsgText = MsgText & "CATPart or CATProduct hAs to be active."
MsgResponse = MsgBox(MsgText, vbExclamation)
End Sub
Function OptimalizacniFce(prtSoucast As Part, prmRidiciParametr As KnowledgewareTypeLib.Parameter, _
prmOptimalizovanyParametr As KnowledgewareTypeLib.Parameter, dblVstupniKrok As Double, _
dblCilovaHodnota As Double, Optional btePresnost As Byte = 3, Optional lngMaxPocetIteraci As Long = 5000) As Integer
Dim dblDump As Double
Dim dblHodnotaPredIteraci, dblHodnotaPoIteraci As Double
Dim dblKrok, dblPresnost As Double
Dim blnUpravenyKrok As Boolean
Dim MsgResponse As Integer
Dim intItKrok, lngIterace As Integer
Dim dblPomocne1, dblPomocne2 As Double
Dim intZnamenko As Integer
dblDump = prmRidiciParametr.Value
dblPresnost = 10 ^ (-btePresnost)
dblKrok = dblVstupniKrok
dblHodnotaPredIteraci = prmOptimalizovanyParametr.Value
intItKrok = 1
lngIterace = 1
intZnamenko = 1
If dblCilovaHodnota < prmOptimalizovanyParametr.Value Then intZnamenko = -1
If Abs(dblCilovaHodnota - prmOptimalizovanyParametr.Value) > dblPresnost Then
Do
blnUpravenyKrok = False
prmRidiciParametr.Value = prmRidiciParametr.Value + dblKrok
On Error Resume Next
prtSoucast.Update
If Err.Number <> 0 Then
OptimalizacniFce = -3
prmRidiciParametr.Value = dblDump
prtSoucast.Update
Exit Function
End If
On Error GoTo 0
dblHodnotaPoIteraci = prmOptimalizovanyParametr.Value
prmRidiciParametr.Value = prmRidiciParametr.Value - dblKrok
dblPomocne1 = Abs(dblCilovaHodnota - dblHodnotaPredIteraci)
dblPomocne2 = Abs(dblHodnotaPoIteraci - dblHodnotaPredIteraci)
If dblPomocne1 < dblPomocne2 Then
If dblPomocne2 <> 0 And dblPomocne1 <> 0 Then
dblKrok = dblKrok / (2 * dblPomocne2 / dblPomocne1)
End If
intItKrok = intItKrok + 1
If intItKrok > 100 Then
OptimalizacniFce = -1
prmRidiciParametr.Value = dblDump
prtSoucast.Update
Exit Function
End If
blnUpravenyKrok = True
End If
Loop Until blnUpravenyKrok = False
Do
Do
prmRidiciParametr.Value = prmRidiciParametr.Value + dblKrok
On Error Resume Next
prtSoucast.Update
If Err.Number <> 0 Then
OptimalizacniFce = -3
prmRidiciParametr.Value = dblDump
prtSoucast.Update
Exit Function
End If
On Error GoTo 0
dblHodnotaPoIteraci = prmOptimalizovanyParametr.Value
lngIterace = lngIterace + 1
CATIA.StatusBar = "Aktuální poèet iteraèních krokù:" & CStr(lngIterace) & "; akt.cílová hodnota:" & prmOptimalizovanyParametr.ValueAsString
If lngIterace > lngMaxPocetIteraci Then
OptimalizacniFce = -2
prmRidiciParametr.Value = dblDump
prtSoucast.Update
Exit Function
End If
Loop Until (intZnamenko * prmOptimalizovanyParametr.Value) >= (intZnamenko * dblCilovaHodnota)
prmRidiciParametr.Value = prmRidiciParametr.Value - dblKrok
dblKrok = dblKrok / 10
Loop Until Abs(dblCilovaHodnota - prmOptimalizovanyParametr.Value) < dblPresnost
prmRidiciParametr.Value = prmRidiciParametr.Value + dblKrok * 10
On Error Resume Next
prtSoucast.Update
If Err.Number <> 0 Then
OptimalizacniFce = -3
prmRidiciParametr.Value = dblDump
prtSoucast.Update
Exit Function
End If
On Error GoTo 0
OptimalizacniFce = lngIterace
Else
OptimalizacniFce = -4
prmRidiciParametr.Value = dblDump
prtSoucast.Update
End If
End Function
Public Function OptimalizacniFceProduct(prdSestava As Product, prmRidiciParametr As KnowledgewareTypeLib.Parameter, _
prmOptimalizovanyParametr As KnowledgewareTypeLib.Parameter, dblVstupniKrok As Double, _
dblCilovaHodnota As Double, Optional btePresnost As Byte = 3, Optional lngMaxPocetIteraci As Long = 5000) As Integer
Dim dblDump As Double
Dim dblHodnotaPredIteraci, dblHodnotaPoIteraci As Double
Dim dblKrok, dblPresnost As Double
Dim blnUpravenyKrok As Boolean
Dim MsgResponse As Integer
Dim intItKrok As Integer
Dim lngIterace As Long
Dim dblPomocne1, dblPomocne2 As Double
Dim intZnamenko As Integer
dblDump = prmRidiciParametr.Value
dblPresnost = 10 ^ (-btePresnost)
dblKrok = dblVstupniKrok
dblHodnotaPredIteraci = prmOptimalizovanyParametr.Value
intItKrok = 1
lngIterace = 1
intZnamenko = 1
If dblCilovaHodnota < prmOptimalizovanyParametr.Value Then intZnamenko = -1
If Abs(dblCilovaHodnota - prmOptimalizovanyParametr.Value) > dblPresnost Then
Do
blnUpravenyKrok = False
prmRidiciParametr.Value = prmRidiciParametr.Value + dblKrok
On Error Resume Next
prdSestava.Update
If Err.Number <> 0 Then
OptimalizacniFceProduct = -3
prmRidiciParametr.Value = dblDump
prdSestava.Update
Exit Function
End If
On Error GoTo 0
dblHodnotaPoIteraci = prmOptimalizovanyParametr.Value
prmRidiciParametr.Value = prmRidiciParametr.Value - dblKrok
dblPomocne1 = Abs(dblCilovaHodnota - dblHodnotaPredIteraci)
dblPomocne2 = Abs(dblHodnotaPoIteraci - dblHodnotaPredIteraci)
If dblPomocne1 < dblPomocne2 Then
If dblPomocne2 <> 0 And dblPomocne1 <> 0 Then
dblKrok = dblKrok / (2 * dblPomocne2 / dblPomocne1)
End If
intItKrok = intItKrok + 1
If intItKrok > 100 Then
OptimalizacniFceProduct = -1
prmRidiciParametr.Value = dblDump
prdSestava.Update
Exit Function
End If
blnUpravenyKrok = True
End If
Loop Until blnUpravenyKrok = False
Do
Do
prmRidiciParametr.Value = prmRidiciParametr.Value + dblKrok
On Error Resume Next
prdSestava.Update
If Err.Number <> 0 Then
OptimalizacniFceProduct = -3
prmRidiciParametr.Value = dblDump
prdSestava.Update
Exit Function
End If
On Error GoTo 0
dblHodnotaPoIteraci = prmOptimalizovanyParametr.Value
lngIterace = lngIterace + 1
CATIA.StatusBar = "Aktuální poèet iteraèních krokù:" & CStr(lngIterace) & "; akt.cílová hodnota:" & prmOptimalizovanyParametr.ValueAsString
If lngIterace > lngMaxPocetIteraci Then
OptimalizacniFceProduct = -2
prmRidiciParametr.Value = dblDump
prdSestava.Update
Exit Function
End If
Loop Until (intZnamenko * prmOptimalizovanyParametr.Value) >= (intZnamenko * dblCilovaHodnota)
prmRidiciParametr.Value = prmRidiciParametr.Value - dblKrok
dblKrok = dblKrok / 10
Loop Until Abs(dblCilovaHodnota - prmOptimalizovanyParametr.Value) < dblPresnost
prmRidiciParametr.Value = prmRidiciParametr.Value + dblKrok * 10
On Error Resume Next
prdSestava.Update
If Err.Number <> 0 Then
OptimalizacniFceProduct = -3
prmRidiciParametr.Value = dblDump
prdSestava.Update
Exit Function
End If
On Error GoTo 0
OptimalizacniFceProduct = lngIterace
Else
OptimalizacniFceProduct = -4
prmRidiciParametr.Value = dblDump
prdSestava.Update
End If
End Function
Public Function VyberParametru(strZprava As String) As KnowledgewareTypeLib.Parameter
Const strFiltr As String = "Parameter, Constraint"
Dim oSelekce As Object
Dim varTempArr As Variant
Dim vararrFiltr() As Variant
Dim strStatus As String
Dim i As Byte
Dim oParam As KnowledgewareTypeLib.Parameter
varTempArr = Split(strFiltr, ",")
ReDim vararrFiltr(UBound(varTempArr))
For i = 0 To UBound(varTempArr)
vararrFiltr(i) = Trim(varTempArr(i))
Next i
strZprava = strZprava & " [ESC]=Strono"
Set oSelekce = CATIA.Application.ActiveDocument.Selection
oSelekce.Clear
CATIA.Application.Visible = True
strStatus = oSelekce.SelectElement3(vararrFiltr, strZprava, False, CATMultiSelTriggWhenSelPerf, False)
Select Case strStatus
Case "Normal"
If TypeName(oSelekce.Item2(1).Value) = "Constraint" Then
If oSelekce.Item2(1).Value.Type = catCstTypeDistance Or _
oSelekce.Item2(1).Value.Type = catCstTypeLength Or _
oSelekce.Item2(1).Value.Type = catCstTypeAngle Or _
oSelekce.Item2(1).Value.Type = catCstTypePlanarAngle Or _
oSelekce.Item2(1).Value.Type = catCstTypeRadius Or _
oSelekce.Item2(1).Value.Type = catCstTypeMajorRadius Or _
oSelekce.Item2(1).Value.Type = catCstTypeMinorRadius Or _
oSelekce.Item2(1).Value.Type = catCstTypeChamfer Or _
oSelekce.Item2(1).Value.Type = catCstTypeChamferPerpEnd Or _
oSelekce.Item2(1).Value.Type = catCstTypeCylinderRadius Then
Set oParam = oSelekce.Item2(1).Value.Dimension
If IsNumeric(oParam.Value) Then
Set VyberParametru = oParam
Else
Set VyberParametru = Nothing
Err.Number = vbObjectError + 50
Err.Source = "Catia"
Err.Description = "Vybrán špatný constrain - nejedná se o èíselnou hodnotu."
End If
Else
Set VyberParametru = Nothing
Err.Number = vbObjectError + 50
Err.Source = "Catia"
Err.Description = "Vybrán špatný constraint - nejedná se o èíselnou hodnotu."
End If
Else
Set oParam = oSelekce.Item2(1).Value
If IsNumeric(oParam.Value) Then
Set VyberParametru = oParam
Else
Set VyberParametru = Nothing
Err.Number = vbObjectError + 50
Err.Source = "Catia"
Err.Description = "Vybrán špatný parametr - nejedná se o èíselnou hodnotu."
End If
End If
Case "Undo"
Case "Redo"
Case "Cancel"
Set VyberParametru = Nothing
Err.Number = vbObjectError + 50
Err.Source = "Catia"
Err.Description = "ESC - zrušena akce"
Case Else
Set VyberParametru = Nothing
Err.Number = vbObjectError + 50
Err.Source = "Catia"
Err.Description = "Nìco špatnì pøi výbìru parametru"
End Select
Set oSelekce = Nothing
Set oParam = Nothing
End Function