Place Equipment From Ribbon Revit 2015: Transaction already started - vb.net

Stack,
I'm programming an external application that works in Autodesk's Revit (2015). I've created a button on the ribbon that allows the user to place a special equipment that I'll use later to read and pass on to another process. I using 'TheBuildingCoder's' 'Family API' examples to do so. The button on the ribbon has an external command set in the .addin file in the ProgramData Directory...
<AddIn Type="Command">
<Assembly>C:\GSN Programs\MyDll.dll</Assembly>
<AddInId>{97715E4F-EA48-4690-8C62-B5D4836FF452}</AddInId>
<FullClassName>RcarsPlugIn.PlaceEquipment</FullClassName>
<VendorId>MyCompany, LLC</VendorId>
<Text>Place Equipment</Text>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
On the button press, I put the command data into a global variable to use throughout the program...
If IsNothing(gv_oGo) Then
gv_oGo = New clsGeneralOperations
gv_oGo.CachedCommandData = exCommandData
gv_oGo.UiApp = exCommandData.Application.ActiveUIDocument.Application
End If
With the CommandData cached I move to place the equipment by user pick...
uiDoc = gv_oGo.UiApp.ActiveUIDocument
oSym = oRF.FindElement(doc, GetType(FamilySymbol), "MyEQUIP")
uiDoc.PromptForFamilyInstancePlacement(oSym)
Public Function FindElement(doc As Document, targetType As Type, sTargetName As String) As Element
Return New FilteredElementCollector(doc).OfClass(targetType).FirstOrDefault(Function(e) e.Name.Equals(sTargetName))
End Function
That's where the problem comes into play. I get an error message sent back from Revit stating that "Placement is not permitted in an already modifiable document. The active transaction must be closed first." The problem is, I haven't started a different transaction. The button onthe ribbon is the first that touched when Revit starts.
Is there a way to loop through the open transactions and find one that is open? Is the document in some state that I don't understand? I'm not sure which direction to turn here... any help would be appreciated.
Thanks,
Runnin...

Ok, one clarifying question - the exception is occurring on
uiDoc.PromptForFamilyInstancePlacement(oSym) line correct? if so, try using a subtransaction to complete your command instead:
Document doc = uiDoc.Document;
using (SubTransaction subtr_fam = new SubTransaction(doc))
{
try
{
uiDoc.PromptForFamilyInstancePlacement(oSym);
}
catch(Exception e)
{
Console.WriteLine(e.StackTrace.ToString());
}
}

Related

Displaying NLog in date descending order

I am using NLog with a VB.Net project:
Private m_logger As NLog.Logger = LogManager.GetCurrentClassLogger()
Issues are populated in the log like this:
Catch ex As Exception
Console.WriteLine("Error: {0}", ex.Message.ToString())
m_logger.Error(ex, "ExtractCalendarInformation")
End Try
Now, this VB too is a console app that is used my another application which is written with Visual C++. If the parent app has detected that there are problems it displays the log file:
void CMeetingScheduleAssistantApp::ShowLogFile(CString strLogFile)
{
if (PathFileExists(strLogFile))
{
CLogDlg dlgLog;
CTextFileRead fileLog(strLogFile);
CString strText = _T("");
fileLog.ReadLine(strText);
while (!fileLog.Eof())
{
strText.Trim();
if (strText.IsEmpty())
continue;
dlgLog.AddLogEntry(strText, true);
fileLog.ReadLine(strText);
}
dlgLog.SetErrorMode(true);
dlgLog.DoModal();
}
}
The problem is that the log file is in date ascebdung order and sometimes users send me screen shots and don't scroll.
Is there anyway to display this error log from Nlog in fdate desending order? And I don't think it is OK to just read the file in reverse.
I include both VB and C++ tags since I might have to make changes in either tool.
I saw this question Write records in descending order in NLog. The thing is my C# tool uses SimpleLogger and that creates log folders in a folder and the log is named by date, and all items in that log are date descending. But I can't use SimpleLogger with VB.Net I don't think.
One option could be to load the file into a vector<CString>, and then just use rbegin() for reverse iteration and inserting file-contents into the dlgLog.
Another option is to investigate how update scrollbar in CTextFileRead after having loaded the file, so scroll-button is moved down to the bottom.
Update
I actually was using CEdit control to display the log contents. So in the end I used the following code to automatically scroll to the bottom:
m_editLogData.LineScroll(m_editLogData.GetLineCount());

"The object does not support this method" - Error when trying to update the subject of an email (MailItem.Subject)

I'm maintaining a C# Outlook add-in. It runs, since many years, in Outlook 2003. Today, a user reported an error I never saw before. For two mails (both from the same sender), she's getting this error message when she tries to process them:
The object does not support this method.
at Microsoft.Office.Interop.Outlook._MailItem.set_Subject(String Subject)
The exception is raised when the add-in tries to update the subject:
private static void ForceReconnectToExchangeServer(Outlook.MailItem mi)
{
mi.Subject = mi.Subject + ""; // <-- HERE
mi.Save();
}
I can see a second error message (a tooltip at the end of the line in Visual Studio):
errorCS0433: The type 'MailItem' exists in both
'Microsoft.Office.Tools.Outlook.Implementation, Version=10.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and
'Microsoft.Office.Tools.Outlook, Version=10.0.0.0, Culture=neutral
(... can't see the rest of the line ....)
Any idea why this is happening? Many thanks!
Note 1: This add-in uses a recent version of Redemption.
Note 2: I'm getting the same error when I forward the message to myself (an process it), even if I delete everything in the message. If I change the mail format to Plain Text however, no error.
Note 3: this problem maybe related to this one, but nobody answered it.
Do you have both references in your project? Make sure there are no conflicts.
Also keep in mind that updating Subject will cause conversation specific properties to be be reset. Resetting the message class (IPM.Note.Dummy, then back to the original one) might be a better idea.
The Microsoft.Office.Tools.Outlook namespace contains a set of classes and interfaces that enable you to create form regions that customize Microsoft Office Outlook forms.
I'd suggest reviewing the code base and remove unused references from the project. Also make sure that the Outlook namespace points to the Microsoft.Office.Interop.Outlook one, for example:
private static void ForceReconnectToExchangeServer(Microsoft.Office.Interop.Outlook.MailItem mi)
{
mi.Subject = mi.Subject + ""; // <-- HERE
mi.Save();
}

File download control - delete file without validation?

Hello XPages programmers.
I work on a simple XPages File Library.
To achieve that i use FileUpload control with FileDownload control.
When i create a new file, i enter its name, and select a file.
I set that uploading a file won't activate a validation, so i can attach a file without a specified name. Additionally i set it to do fullrefresh, so uploading a file takes place in an instant and a file is visible in FileDownload control.
Problem occurs, when i want to delete that attachment using garbage icon of FileDownload - i can't set it to run without walidation.
Is there any workaround avaiable?
Any help will be appreciated.
I used the workaround Mark Leusink suggested - created a simmilar button (used image from filedownload control) and then set it for full refresh with process data without validation property.
Code in JSSS
function deleteAttachments()
{
var attList = dDocument.getAttachmentList("Document_Attachment");
for(var i=0; i<attList.size(); i++)
{
var att:String = attList[i];
dDocument.removeAttachment("Document_Attachment", att.getName() );
}
}
Surely it can be used for delete a specific attachment by getting attachment name from rowdata in a repeater and use DATASOURCE.removeAttachment method.
Thanks for your support!

ObjectARX SDK for c#

For last two days I have looking for sample code with steps which may help me to understand the Autocad API. so I can use the code in C#.
[CommandMethod("LISTGEn")]
public static void ListEntities()
{
Document acDoc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Open the Block table record for read
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for read
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],OpenMode.ForRead) as BlockTableRecord;
int nCnt = 0;
acDoc.Editor.WriteMessage("\nModel space objects: ");
// Step through each object in Model space and
// display the type of object found
foreach (ObjectId acObjId in acBlkTblRec)
{
acDoc.Editor.WriteMessage("\n" + acObjId.ObjectClass.DxfName);
nCnt = nCnt + 1;
}
acDoc.Editor.WriteMessage(nCnt.ToString());
// If no objects are found then display a message
if (nCnt == 0)
{
acDoc.Editor.WriteMessage("\n No objects found");
}
// Dispose of the transaction
}
}
I can run the above code, but it's not functioning properly. It's difficult for me to understand how to get it work with Autocad. I have OjectARX SDK referenced,
I am working with VS2010 and Autocad 2012. Thank You for your help.
Ok, I got it only thing that is being required
1.) is to create a class library
2.) Then need to enter the above code in the class.
3.) Build your project by pressing F5.
4.) A DLL will be created in the bin/debug/ folder of your project
5.) Open Autocad.
6.) Write netload command.
7.) Select the DLL created and then write command "LISTGEN" and than kaboom it will show all the objects in your project.
To avoid having to manually netload your dll, you can use a temporary fix for debugging and write a lisp file to do it for you
(Command "netload" "path/to/your/.dll")\n
Or you can use \\
Take a look at my github. The link is on my profile. Look over the reference library, it's highly simplified for object model manipulation.
If you have any questions feel free to email me.

Override the upload function of a file upload control

I want to override the upload function of a file upload control in order to add the functionality that I need. I am trying to adapt the code from the following link to my case
Auto-save doc after delete of attachment in File Download control?
by changing the type of the second parameter to com.ibm.xsp.component.xp.XSPFileUpload, i.e.:
function rekOverrideFileDownloadAction( component:javax.faces.component.UIOutput, fDownload:com.ibm.xsp.component.xp.XSPFileUpload ){
and the code in the MethodBinding mBinding and by using the name of my file upload control, i.e.:
var mBinding = facesContext.getApplication().createMethodBinding("#{javascript:print('Uploaded');}", null );
overrideFileDownloadAction( getComponent( 'fileUpload1' ) );
Unfortunately, a javax.faces.FacesException occurs.
Can anyone help me to modify this code in order to just print this message when the user uploads a file?
Stack Trace:
javax.faces.FacesException
javax.faces.FacesException.<init>(FacesException.java:97)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:86)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:210)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:96)
com.ibm.xsp.controller.FacesControllerImpl.execute(FacesControllerImpl.java:250)
com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:209)
com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:204)
com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138)
com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576)
com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1281)
com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:847)
com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796)
com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565)
com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1265)
com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:653)
com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:476)
com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:341)
com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:297)
com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
java.lang.NullPointerException
com.ibm.xsp.actions.ActionGroup.invoke(ActionGroup.java:135)
com.ibm.xsp.actions.ActionGroup.invoke(ActionGroup.java:135)
com.ibm.xsp.application.ActionListenerImpl.processAction(ActionListenerImpl.java:60)
javax.faces.component.UICommand.broadcast(UICommand.java:324)
com.ibm.xsp.component.UIEventHandler.broadcast(UIEventHandler.java:366)
com.ibm.xsp.component.UIViewRootEx.broadcast(UIViewRootEx.java:1535)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:307)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:428)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:94)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:210)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:96)
com.ibm.xsp.controller.FacesControllerImpl.execute(FacesControllerImpl.java:250)
com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:209)
com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:204)
com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138)
com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576)
com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1281)
com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:847)
com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796)
com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565)
com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1265)
com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:653)
com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:476)
com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:341)
com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:297)
com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
I also noticed that if I add a script to an event, e.g. onChange, so that an event handler is created no exception occurs. So I think the exception is thrown because there is no event handler and that leads to a null pointer. For now I have added the functionality I need to the onChange event and it is ok, but it would be nice if someone could tell me if there is a way to override it.
Thank you in advance!
What are you trying to do? I think that it is not possibile with the snippet (it overwrites an event handler of the download link which is available for an Upload Control only).
Maybe this snippet can help you: http://openntf.org/XSnippets.nsf/snippet.xsp?id=replace-attachment-when-uploading-a-new-attachment