I have modeled a building in OpenModelica using Buildings library. I am curretly using OMPython and OMCSessionZMQ to set and optimize OpenModelica parameters in Python.
I just found out that for some parameters isChangeable = False, i.e., mSenFac, and I cannot use mod.setParameters( ) to set those parameters.
mSenFac can be found in Buildings.Fluid.MixingVolumes.MixingVolume, which is later used in Buildings.ThermalZones.ReducedOrder.RC.
Instead, I have been suggested to use
mod.sendExpression("setParameterValue(BuildingModels.oneElement, thermalZoneOneElement.mSenFac, 5), parsed = False)" and rebuild the model using mod.buildModel( ) API.
BuildingModels.oneElement is my model name
thermalZoneOneElement.mSenFac is the parameter I want to set.
However, this method also did not work for me, which I don't know why.
I need to be able to set mSenFac in iterations in an optimization algorithm. I would appreciate it if anyone can answer the following questions:
Is it possible to make isChangeable = True for mSenFac?
Is there any other way to set mSenFac using OMPython?
Best regards,
Farnaz
Running this script:
loadString("
package BuildingModels
model oneElement
Integer mSenFacParameter = 1;
Buildings.ThermalZones.ReducedOrder.RC.OneElement thermalZoneOneElement;
end oneElement;
end BuildingModels;
"); getErrorString();
list(BuildingModels.oneElement); getErrorString();
// using setParameterValue can only set top level parameters
setParameterValue(BuildingModels.oneElement, mSenFacParameter, 6); getErrorString();
list(BuildingModels.oneElement); getErrorString();
// using setComponentModifierValue can set component modifiers
setComponentModifierValue(BuildingModels.oneElement, thermalZoneOneElement.mSenFac, $Code(=6)); getErrorString();
list(BuildingModels.oneElement); getErrorString();
// using setComponentModifierValue can set component modifiers
setComponentModifierValue(BuildingModels.oneElement, thermalZoneOneElement.mSenFac, $Code(=mSenFacParameter)); getErrorString();
list(BuildingModels.oneElement); getErrorString();
gives you:
true
""
"model oneElement
Integer mSenFacParameter = 1;
Buildings.ThermalZones.ReducedOrder.RC.OneElement thermalZoneOneElement;
end oneElement;"
""
Ok
""
"model oneElement
Integer mSenFacParameter = 6;
Buildings.ThermalZones.ReducedOrder.RC.OneElement thermalZoneOneElement;
end oneElement;"
""
Ok
""
"model oneElement
Integer mSenFacParameter = 6;
Buildings.ThermalZones.ReducedOrder.RC.OneElement thermalZoneOneElement(mSenFac = 6);
end oneElement;"
""
Ok
""
"model oneElement
Integer mSenFacParameter = 6;
Buildings.ThermalZones.ReducedOrder.RC.OneElement thermalZoneOneElement(mSenFac = mSenFacParameter);
end oneElement;"
""
Basically set the component modifier, build the code, simulate it, take the results.
Related
I was using the MOTO BIT Mdict as my dictionary component, putting all my translations in the Application object as per the below code, and it worked fine, until the component expired 2 days ago for unknown reasons, 12 years later on.
The MOTO Bit website is not replying - so now I seek help if anyone knows how I can reprogram the code below to use with the build in asp scripting.dictionary instead. Is it possible at all?
Function Write(strID, Comment)
If ValidNumber(strID) Then
If (IsObject(Application("Translation_" & StoryCountry)) = False) OR Debugf = True Then
SET objDic = Server.CreateObject("Multi.Dictionary")
'Load the translations into the dic object
set toRs = conn.execute("EXEC dbo.GetTranslationsByCountryID " & StoryCountry)
If Not toRs.Eof Then
tRow = toRs.GetRows()
For tx = 0 To UBound(tRow, 2)
IF objDic.Exists(tRow(0, tx)) THEN
ELSE
strTranslationKey = tRow(0, tx)
strTranslationText = tRow(1, tx)
objDic.Add strTranslationKey, strTranslationText
END IF
Next
SET Application("Translation_" & StoryCountry) = objDic
End If
Set toRs = Nothing
End If
Write = Application("Translation_" & StoryCountry)(strID)
Else
Write = "Invalid"
End If
End Function
Unfortunately, Lord Svendson, using Scripting.Dictionary objects at the Application level is not allowed. When you attempt to SET Application("Translation_" & StoryCountry) = objDic, it errors for this reason. You will need to find a workaround to using Scripting.Dictionary
i have this subroutine that i use to make labels. for some reason i cant just make another subroutine where instead of "CGI_SAMPLE_LABEL" it uses "YCI_SAMPLE_LABEL" because of other subroutines. any suggestions on how i can add this so that it chooses either one or the other. if tried using WHERE OR but that didn't work. i edited some of the tags because LIMS basic language is also like smalltalk.
LabelType = "CGI_SAMPLE_LABEL"
pTableNameStr = "SAMPLE"
pLabelNameStr = "CGI_SAMPLE_LABEL"
'Breakpoint(aReason)
NumSamples = Ubound(selectedObjects, 1)
FOR X = 1 TO NumSamples
SampleNumber = selectedObjects[x]
pKeyNameArr[1] = SampleNumber
pNumLabelsInt = 1
pLabelNameStr = "CGI_SAMPLE_LABEL"
pReasonStr = "Auto Label Generation"
pActivityStr = "Label printed for sample logged event"
GOSUB FN_LABEL_PRINT_ALL
NEXT 'Sample
RETURN
I have through an API fetched my data as an XML, and I wish to cycle through nodes (there are several of the same type) and add them to certain fields/a table.
Example from the XML-file:
<HistRating
xmlns="">
<EndrAr>2020</EndrAr>
<EndrMnd>7</EndrMnd>
<Rating>A</Rating>
</HistRating>
<HistRating
xmlns="">
<EndrAr>2019</EndrAr>
<EndrMnd>6</EndrMnd>
<Rating>A</Rating>
</HistRating>
I have tried the following format (at this point the XML I need is in a string in xmlDoc xmlDoc = CreateObject("MSXML2.DOMDocument.6.0"). Fully aware that this is not a really "sexy" way to write it, but I'm new at this game:
Set nodeXML = xmlDoc.getElementsByTagName("EndrAr")
Range("G1").Value = nodeXML(1).Text
Range("H1").Value = nodeXML(2).Text
Range("I1").Value = nodeXML(3).Text
Set nodeXML = xmlDoc.getElementsByTagName("EndrMnd")
Range("G2").Value = nodeXML(1).Text
Range("H2").Value = nodeXML(2).Text
Range("I2").Value = nodeXML(3).Text
Set nodeXML = xmlDoc.getElementsByTagName("Rating")
Range("G3").Value = nodeXML(1).Text
Range("H3").Value = nodeXML(2).Text
Range("I3").Value = nodeXML(3).Text
This works great as long as all three items are there. Unfortunately that is not given. If it is a new company i.e. (3) wont exist (there is one line per year above), and I would like to either set the cell to Blank or No value or something.
The result from when I run the above code:
But if I try to add a line 4 to test what happens if value does not exists I get the following (for obvious reasons)
What I would love some help with is:
Can I by some "magic" add a ifmissing (tried it, but could not get it to work)?
Other ways to add a if variable is not found, input following into cell
Or are there a complete different way I should have solved this?
This is to add accounting data from last X available years (where X is ie 4, or less if not 4 is available) from 30 nodes.
You could use an Error trapping Function. Note in the code below we choose not to use the returned boolean.
Dim myTest as String
.
.
TryReadingXmlNode nodeXML,1, myText
Range("G1").Value = myText
.
.
Public Function TryReadingXmlNode(ByVal ipNode as object, ByVal ipIndex as Long, ByRef opText as string) as boolean
On Error Resume Next
opText=ipNode.Item(ipIndex).Text
TryReadingXmlNode=Len(opText)>0
If err.number>0 then opText="NoValue"
on Error Goto 0
End Function
Start by querying all of the HistRating elements, then loop over that collection:
Const MAX_YEARS As Long = 4
Dim ratings, rating, c As Range, i as Long
Set c= Range("A1")
Set ratings = xmlDoc.getElementsByTagName("HistRating")
For Each rating in ratings
c.offset(0, i) = rating.getElementsByTagName("EndrAr")(0).Text
c.offset(1, i) = rating.getElementsByTagName("EndrMnd")(0).Text
c.offset(2, i) = rating.getElementsByTagName("Rating")(0).Text
i = i + 1
If i >= MAX_YEARS Then Exit For 'exit if processed enough nodes
Next rating
I am trying to export some text from annotation fields in Nuance Power PDF to Excel using VBA. I added the Nuance Power PDF reference to Excel VBA (PDF Plus).
I used it and it works well but the text returned from fields is empty.
Set PDFApp = CreateObject("NuancePDF.App")
Set dvDoc = CreateObject("NuancePDF.DVDoc")
dvDoc.Open("\\adpdc-2\Users$\a.goudinoux\Documents\Macro Formulaire\fiche.pdf")
Set ddDoc = dvDoc.GetDDDoc()
Set ddPage = ddDoc.AcquirePage(0)
nbannots = ddPage.GetNumAnnots() - 1
For i = 0 To nbannots
Texte = ""
Set ddAnnot = ddPage.GetAnnot(i)
Set ddText = ddDoc.CreateTextSelect(0, ddAnnot.GetRect())
ThisWorkbook.Sheets(1).Cells(1, i) = ddAnnot.GetTitle()
For k = 0 To ddText.GetNumText()
Texte = Texte & ddText.GetText(k)
Next
ThisWorkbook.Sheets(1).Cells(2, i) = Texte
Next
Part of the PDF document :
Results :
As you can see the first line is working but not the second one.
I thought the problem was with ddText but ddText.GetNumText() gives the right number of text elements in the text selection (ex : 2, 5, 4, etc...) when I run my program in Debug Mode.
I think the problem is from the function GetText(k).
I made it work once but I can't find my code back..
Do you see any mistake ?
Either your annotations are more complex than indicated or you're overthinking it.
Just read the annotation with GetContents and call it a day.
Set PDFApp = CreateObject("NuancePDF.App")
Set dvDoc = CreateObject("NuancePDF.DVDoc")
dvDoc.Open("\\adpdc-2\Users$\a.goudinoux\Documents\Macro Formulaire\fiche.pdf")
Set ddDoc = dvDoc.GetDDDoc()
Set ddPage = ddDoc.AcquirePage(0)
nbannots = ddPage.GetNumAnnots() - 1
For i = 0 To nbannots
Set ddAnnot = ddPage.GetAnnot(i)
ThisWorkbook.Sheets(1).Cells(1, i) = ddAnnot.GetTitle
ThisWorkbook.Sheets(1).Cells(2, i) = ddAnnot.GetContents
Next i
Objective
To search through a bunch of lines in a text file, and if a match is found populate that line in a Options list that is displayed in HTA.
Eg: If 'Setup' is found in 5 lines out of total 10, all the 5 lines need to be populated as 'Options'
Code
Set objFSO = CreateObject("Scripting.Filesystemobject")
Set objRegEx = New RegExp
With objRegEx
.Pattern = "(\b" & "setup" & "\b)"
.IgnoreCase = True
.Global = True
End With
Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
Contents = objOpen.ReadAll
Set objMatchAll = objRegEx.Execute( Contents )
If objMatchAll.count > 0 Then
Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
Do Until objOpen.AtEndOfStream
Line = objOpen.ReadLine
Set objMatchAny = objRegEx.Execute( Line )
If objMatchAny.count > 0 Then
Set objOption = Document.createElement("OPTION")
objOption.Text = Line
objOption.Value = Line
ValuesList.add objOption
'Matched = Matched & vbNewLine & Line
MatchCount = MatchCount + 1
End If
Loop
Else
MsgBox "No results"
End If
Explanation
The code looks for the term 'setup' (of course this is dynamically populated at the time of execution) in the file 'FileList.lst'. When results are found an 'Option' object is generated and added to the 'ValuesList' List which is in an HTML body using tags.
Note 1: The reason i generate an 'Options' object instead of just loading the line is so that we can populate the tag. The tag is used so we can select any one of the search result.
Note 2: The reason the 'Contents' variable is created so that incase if there are no matches at all, it need not go to each line to find a match, which would take longer to just display that message.
Problem
The code works fine, tested upto 150 results (outcome), but when there is a large number of matches my HTA freezes.
Question
Can the existing code be modified to perform better, like a different method to instead of creating the an 'Options' object, an alternate method to generate the 'ValuesList' ?
Instead of running two objRegEx search results, is there way to return the matched line from 'Contents' Varialable ?
Update
Ok, i ran my script without the objOption part which is not creating and adding options to my ValuesList, only regexp parsing through 58k lines, also resulting in 58k matches and the outcome was 3secs ... so looks like i need an alternative to populate my HTA options list ... its not able to handle that many options to select from ... any alternatives ? I used the same logic in a browser and the entire browser freezes ...
It seems like you really only care about whether or not the regex matches in a particular line or not. Since you don't need to know how many matches occurred, nor do you need the actual match text, you can use the Test method instead. This should be faster because it will stop after the first match, plus it doesn't have to construct the Matches collection. I'd also leave the Global property at its default value of False for pretty much the same reason, but if you're just using the Test method, I don't think the Global property matters.
Thanks to Cheran Shunmugavel i found out that the best way is to use DocumentFragments. I impleted that concept in my code and the results were great !
New Code
Set objFSO = CreateObject("Scripting.Filesystemobject")
Set objRegEx = New RegExp
With objRegEx
.Pattern = "(\b" & "setup" & "\b)"
.IgnoreCase = True
.Global = True
End With
Set objFragment = Document.createDocumentFragment()
Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
Contents = objOpen.ReadAll
Set objMatchAll = objRegEx.Execute( Contents )
If objMatchAll.count > 0 Then
Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
Do Until objOpen.AtEndOfStream
Line = objOpen.ReadLine
Set objMatchAny = objRegEx.Execute( Line )
If objMatchAny.count > 0 Then
Set objOption = Document.createElement("OPTION")
objOption.innerHTML = Line
objFragment.appendchild objOption
MatchCount = MatchCount + 1
End If
Loop
ViewList.appendChild objFragment.cloneNode(True)
Else
MsgBox "No results"
End If
Old Code : 53mins 23secs
New Code : 31secs