Mathcad Object

04/05/2008 - 08:27 por Alvaro | Informe spam
Hola. Escribí este código para ejecutar Mathcad en Excel. El primer
argumento es un string con el nombre del objeto: el que se pone en el cuadro
de nombres. Funciona bastante bien, pero me gustarían dos cosas:

1. Usar paramarray, pero fallo, no me queda bien.
2. Aparentemente llama tantas instancias del programa como objectos halla.
Necesitaría que llame a mathcad una sola vez, pues aparenta ser muy lenta la
función así como está.

Nota: IsVector e IsMatrix son pequeñas funciones que devuelven un bool. No
las pongo porque no son mías, se las pedí prestadas a Volpi, de foxteam.

Option Base 1
Option Explicit

Public Function mcad(mcd As String, Optional a1 As Variant, _
Optional a2 As Variant, Optional a3 As Variant, Optional a4 As Variant,
Optional a5 As Variant, _
Optional a6 As Variant, Optional a7 As Variant, Optional a8 As Variant,
Optional a9 As Variant) _
As Variant

On Error GoTo ErrLbl

Dim ws As Worksheet
Dim MathcadObject As Variant, obj As OLEObject
Dim outRe As Variant, outIm As Variant
Dim inRe As Variant, inIm As Variant
Dim h As Long, k As Long
Dim i As Long, j As Long
Dim n As Long, m As Long
Dim inx As String
Dim A(1 To 9) As Variant


k = 0
If (Not IsMissing(a1)) Then
A(k + 1) = a1: k = k + 1
ElseIf (Not IsMissing(a2)) Then
A(k + 1) = a2: k = k + 1
ElseIf (Not IsMissing(a3)) Then
A(k + 1) = a3: k = k + 1
ElseIf (Not IsMissing(a4)) Then
A(k + 1) = a4: k = k + 1
ElseIf (Not IsMissing(a5)) Then
A(k + 1) = a5: k = k + 1
ElseIf (Not IsMissing(a6)) Then
A(k + 1) = a6: k = k + 1
ElseIf (Not IsMissing(a7)) Then
A(k + 1) = a7: k = k + 1
ElseIf (Not IsMissing(a8)) Then
A(k + 1) = a8: k = k + 1
ElseIf (Not IsMissing(a9)) Then
A(k + 1) = a9: k = k + 1
End If

'Activate the Mathcad object
For Each ws In Worksheets
For Each obj In ws.OLEObjects
If obj.name = mcd Then
obj.Activate
obj.AutoLoad = True
Set MathcadObject = obj.Object
End If
Next obj
Next ws

For k = 1 To k

' Setup arguments
inRe = A(k)
inIm = A(k)
If IsMatrix(inIm) Then
n = UBound(inIm, 1)
m = UBound(inIm, 2)
ReDim inIm(1 To n, 1 To m)
For i = 1 To n
For j = 1 To m
inIm(i, j) = 0
Next j
Next i
Else
If IsVector(inIm) Then
n = UBound(inIm)
ReDim inIm(1 To n)
For i = 1 To n
inIm(i) = 0
Next i
Else
inIm = 0
End If
End If

' Send to Mathcad in0, in1, etc
inx = "in" & CStr(k - 1)
Call MathcadObject.SetComplex(inx & CStr(k), inRe, inIm)

Next k

' Recalculate
Call MathcadObject.Recalculate

' Read results from out0 to Excel's outRe, outIm
Call MathcadObject.getComplex("out0", outRe, outIm)

' Send the last value again to actualize mcad image
Call MathcadObject.SetComplex(inx, inRe, inIm)

' Recalculate again
Call MathcadObject.Recalculate
Call MathcadObject.getComplex("out0", outRe, outIm)

' Set the answer: Not implemented yet complex answers
'If outIm = 0 Then
mcad = outRe
'Else
' mcad = CStr(outRe) & " + I " & CStr(outIm)
'End If

ErrLbl:

End Function

Preguntas similare

Leer las respuestas

#1 Héctor Miguel
04/05/2008 - 10:02 | Informe spam
hola, Alvaro !

Escribi este codigo para ejecutar Mathcad en Excel. El primer argumento es un string con el nombre del objeto:
el que se pone en el cuadro de nombres. Funciona bastante bien, pero me gustarian dos cosas:
1. Usar paramarray, pero fallo, no me queda bien.
2. Aparentemente llama tantas instancias del programa como objectos halla. Necesitaría que llame a mathcad una sola vez, pues aparenta ser muy lenta la funcion asi como esta.



1) NO expones la forma en que has intentado usar un ParamArray (hubiera sido bueno) y... (hasta donde se)...
(solo como comentario) cuando un codigo If...ElseIf...End If -> "entra" a un apartado, se omiten los restantes

este seria un ejemplo (sumamente basico) del uso del ParamArray, cuando desconoces cuantos elementos podria contener
una funcion para "simular" la funcion integrada de excel =suma(...)

Function Sumando(ParamArray Rango()) As Variant
Dim Lote As Integer, Celda As Range, Total As Double
For Lote = LBound(Rango) To UBound(Rango)
For Each Celda In Rango(Lote)
If IsError(Celda) Then
Sumando = Celda
Exit Function
End If
Total = Total + Val(Celda)
Next
Next
Sumando = Total
End Function

2) NO es "aparentemente" (sino realmente) que se estan haciendo tantas llamadas como objetos se encuentran...
tienes un bucle For...Next para hacer un recorrido por cada hoja...
y dentro de cada hoja OTRO bucle For...Next para instanciar un MathcadObject por cada objeto en cada hoja :-((

por lo demas, comprueba si instanciando un solo objeto (matchcad) puedes cambiar la referencia a los objetos de cada hoja -?-
(desconozco el modelo de objetos de mathcad) :-(

saludos,
hector.

__ el resto de la consulta y codigo expuesto __
Nota: IsVector e IsMatrix son pequenas funciones que devuelven un bool.
No las pongo porque no son mias, se las pedí prestadas a Volpi, de foxteam.

Option Base 1
Option Explicit

Public Function mcad(mcd As String, Optional a1 As Variant, _
Optional a2 As Variant, Optional a3 As Variant, Optional a4 As Variant, Optional a5 As Variant, _
Optional a6 As Variant, Optional a7 As Variant, Optional a8 As Variant, Optional a9 As Variant) _
As Variant

On Error GoTo ErrLbl

Dim ws As Worksheet
Dim MathcadObject As Variant, obj As OLEObject
Dim outRe As Variant, outIm As Variant
Dim inRe As Variant, inIm As Variant
Dim h As Long, k As Long
Dim i As Long, j As Long
Dim n As Long, m As Long
Dim inx As String
Dim A(1 To 9) As Variant

k = 0
If (Not IsMissing(a1)) Then
A(k + 1) = a1: k = k + 1
ElseIf (Not IsMissing(a2)) Then
A(k + 1) = a2: k = k + 1
ElseIf (Not IsMissing(a3)) Then
A(k + 1) = a3: k = k + 1
ElseIf (Not IsMissing(a4)) Then
A(k + 1) = a4: k = k + 1
ElseIf (Not IsMissing(a5)) Then
A(k + 1) = a5: k = k + 1
ElseIf (Not IsMissing(a6)) Then
A(k + 1) = a6: k = k + 1
ElseIf (Not IsMissing(a7)) Then
A(k + 1) = a7: k = k + 1
ElseIf (Not IsMissing(a8)) Then
A(k + 1) = a8: k = k + 1
ElseIf (Not IsMissing(a9)) Then
A(k + 1) = a9: k = k + 1
End If

'Activate the Mathcad object
For Each ws In Worksheets
For Each obj In ws.OLEObjects
If obj.name = mcd Then
obj.Activate
obj.AutoLoad = True
Set MathcadObject = obj.Object
End If
Next obj
Next ws

For k = 1 To k

' Setup arguments
inRe = A(k)
inIm = A(k)
If IsMatrix(inIm) Then
n = UBound(inIm, 1)
m = UBound(inIm, 2)
ReDim inIm(1 To n, 1 To m)
For i = 1 To n
For j = 1 To m
inIm(i, j) = 0
Next j
Next i
Else
If IsVector(inIm) Then
n = UBound(inIm)
ReDim inIm(1 To n)
For i = 1 To n
inIm(i) = 0
Next i
Else
inIm = 0
End If
End If

' Send to Mathcad in0, in1, etc
inx = "in" & CStr(k - 1)
Call MathcadObject.SetComplex(inx & CStr(k), inRe, inIm)

Next k

' Recalculate
Call MathcadObject.Recalculate

' Read results from out0 to Excel's outRe, outIm
Call MathcadObject.getComplex("out0", outRe, outIm)

' Send the last value again to actualize mcad image
Call MathcadObject.SetComplex(inx, inRe, inIm)

' Recalculate again
Call MathcadObject.Recalculate
Call MathcadObject.getComplex("out0", outRe, outIm)

' Set the answer: Not implemented yet complex answers
'If outIm = 0 Then
mcad = outRe
'Else
' mcad = CStr(outRe) & " + I " & CStr(outIm)
'End If

ErrLbl:

End Function
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida