Select to view content in your preferred language

save map document

5005
10
02-01-2011 06:05 AM
TanaHaluska
Emerging Contributor
Hello
I am new to VB and .NET, can anyone tell me what I am doing wrong?  I am using arcmap v10 with MS Visual Studio Express 2008.  I just want to save my map document without presenting a dialog box to the user. The code snippet below does not produce an error, but the map document does not get saved either. Thanks
tlh

Dim pMxDoc As IMxDocument = DirectCast(m_app.document, IMxDocument)
Dim pMap As IMap = pMxDoc.FocusMap
Dim pMapDoc As IMapDocument = pMap
Dim mxdPathName As String

mxdPathName = strDefaultWorkspace & "\" & frmWSIn.txtMapDocName.Text
pMapDoc.SaveAs(mxdPathName)
0 Kudos
10 Replies
RuchiraWelikala
Regular Contributor
Use Try and Catch around your code.
Sub WhateverName()
[INDENT]
Try
Dim pMxDoc As IMxDocument = DirectCast(m_app.document, IMxDocument)
Dim pMap As IMap = pMxDoc.FocusMap
Dim pMapDoc As IMapDocument = pMap
Dim mxdPathName As String

mxdPathName = strDefaultWorkspace & "\" & frmWSIn.txtMapDocName.Text
pMapDoc.SaveAs(mxdPathName) 
Catch ex as Exception
  Msgbox(ex.Message)
End Try
[/INDENT]
End Sub
0 Kudos
TanaHaluska
Emerging Contributor
Thanks, but the try structure did not reveal any errors.  Anyone have other ideas?
thanks!
tlh
0 Kudos
JeffreyHamblin
Occasional Contributor
I am working in C#, so forgive me using that instead of VB.

If I do a straight conversion of the VB code to C# (also in VS 2008 Express):

//Dim pMxDoc As IMxDocument = DirectCast(m_app.document, IMxDocument)
IMxDocument mxDocument = ArcMap.Document;
//Dim pMap As IMap = pMxDoc.FocusMap
IMap map = mxDocument.FocusMap;
//Dim pMapDoc As IMapDocument = pMap
IMapDocument mapDocument = map as IMapDocument;
//Dim mxdPathName As String
//mxdPathName = strDefaultWorkspace & "\" & frmWSIn.txtMapDocName.Text
string mxdPathName = "C:/temp/testsave.mxd";
//pMapDoc.SaveAs(mxdPathName)
mapDocument.SaveAs(mxdPathName, false, false);


I get the following runtime exception on the SaveAs call:
Object reference not set to an instance of an object.

If I don't use the currently loaded map, and instead open an existing one, the SaveAs works:

IMapDocument mapDocument = new MapDocumentClass();
mapDocument.Open("C:/temp/mymap.mxd", "");
string mxdPathName = "C:/temp/testsave.mxd";
mapDocument.SaveAs(mxdPathName, false, false);


So, I suppose the question is: how do we get a reference to ArcMap's current map as an IMapDocument?

I tried:

IMapDocument mapDocument = (IMapDocument)ArcMap.Document;
string mxdPathName = "C:/temp/testsave.mxd";
mapDocument.SaveAs(mxdPathName, false, false);


That results in the following runtime exception on the SaveAs call:
Not implemented (Exception from HRESULT: 0x80004001 (E_NOTIMPL)).

According to the API reference, the MxDocument CoClass implements IMapDocument, so I am stumped.


-Jeff
0 Kudos
JeffreyHamblin
Occasional Contributor
I spent a little more time on this... and could not find any way to get an IMapDocument reference from ArcMap's current document. Even though, the API documentation shows MxDocument implementing IMapDocument, I don't think that is the case.

I was able to put together a different approach that seems to work (in C#):

// Load the current map document's file into a new IMapDocument 
IMapDocument mapDocument = new MapDocumentClass();
mapDocument.Open(((IDocumentInfo2)ArcMap.Document).Path, "");
// Replace the contents with the current contents
mapDocument.ReplaceContents((IMxdContents)ArcMap.Document.PageLayout);
// Save to a different file
mapDocument.SaveAs("C:/temp/testsave.mxd", mapDocument.UsesRelativePaths, false);
mapDocument.Close();


My guess at your VB code would be (I don't have VB installed to test it):
// Load the current map document's file into a new IMapDocument 
Dim pDocInfo as IDocumentInfo2 = DirectCast(m_app.Document, IDocumentInfo2)
Dim pCurDocPath as String = pDocInfo.Path
Dim pMapDocument as IMapDocument = New MapDocumentClass()
pMapDocument.Open(pCurDocPath, String.Empty)
// Replace the contents with the current contents
pMapDocument .ReplaceContents(CType(m_app.Document.PageLayout, IMxdContents))
// Save to a different file
mxdPathName As String = strDefaultWorkspace & "\" & frmWSIn.txtMapDocName.Text
pMapDocument.SaveAs(mxdPathName, pMapDocument.UsesRelativePaths, False)
pMapDocument.Close()


I have not done anything near to thorough testing, and I suspect there must be a better way to do this.

But I hope this helps 🙂

-Jeff
0 Kudos
NeilClemmons
Honored Contributor
Unless I'm missing something in your code the problem is that you're setting your IMapDocument using the document's focus map.  It's the MxDocument class that implements IMapDocument, not the Map class.  You should be setting the IMapDocument reference using the IMxDocument reference, not the focus map.  I haven't tried it so I don't know if it's actually implemented or not.  I would assume it is since the developer help says it is (and this is new at 10).  You can also save the document using the IApplication interface, which is how it has been done in the past.
0 Kudos
RuchiraWelikala
Regular Contributor
The code below is how I did it trying to recreate your situation. 
but as Neil mentioned above, the m_application.SaveDocument works just fine.
Also, you cannot implement MxDocument to MapDocument.


    Public Sub SaveDoc()
        Try
            Dim pMxDoc As IMxDocument = m_application.Document
            Dim pMap As IMap = pMxDoc.FocusMap
            Dim pmxdPathName As String
            Dim pMapDoc As IMapDocument = New MapDocument
            Dim pMxdContents As IMxdContents = pMap
            pmxdPathName = "C:\Documents and Settings\ruchira.welikala\Desktop\GIS Stuff\PracticeShapefiles\TestMXD" & Math.Round(Date.Now.Millisecond, 3) & ".mxd"
            pMapDoc.[New](pmxdPathName)
            pMapDoc.ReplaceContents(pMxdContents)
            pMapDoc.SetActiveView(pMxDoc.ActiveView)
            pMapDoc.Save(True, False)

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
0 Kudos
JeffreyHamblin
Occasional Contributor
Looking back at what the original poster wrote:
"I just want to save my map document without presenting a dialog box to the user."

I have been assuming they want to save a copy of the current document's state, since they used SaveAs.

Using IMapDocument Save or SaveAs presents some potential issues.

In rwelikal's code, an IMap (FocusMap) is used to replace the contents. In my brief testing this only saves the active dataframe to the new mxd. That is why I replaced the contents with the PageLayout, which seems to preserve all the data frames.

However, the documentation for IMapDocument also states:
"since it is not tied to the ArcMap application, application-specific functionality in the MapDocument will not be persisted.  Examples of application specific functionality are toolbar settings, UI customizations, VBA projects, and ArcMap graphs."
So it is not the same as saving the file from within ArcMap.


Neil mentioned IApplication, which has the methods SaveAsDocument and SaveDocument. I don't know how I overlooked those in my searches, but that would seem the best method:

// This successfully saves a copy of the current document to a new location (C#):
ArcMap.Application.SaveAsDocument(@"C:\temp\testsaveIapp.mxd", true);


So, big thanks to Neil for the pointing us in the right direction.

-Jeff
0 Kudos
TanaHaluska
Emerging Contributor
thanks to all who responded.  I will try out the suggestions and let you know what worked. I appreciate everyone's help.
tlh
0 Kudos
TanaHaluska
Emerging Contributor
This code below that rwelikal provided saved the document in the folder. I'm not savy enough to understand what Neil was telling me.  I would like my addin to continue working with the saved map (I think Neil was trying to tell me that this code won't accomodate that.)  If anyone can elaborate on what Neil is explaining, I would appreciate it.
thanks
tlh
            Dim pMxDoc As IMxDocument = DirectCast(m_app.document, IMxDocument)
            Dim pMap As IMap = pMxDoc.FocusMap
            Dim pMapDoc As IMapDocument = New MapDocument
            Dim pMxdContents As IMxdContents = pMap
            Directory.CreateDirectory(strDefaultWorkspace & "\" & frmWSIn.txtOutFolderName.Text)
            pMapDoc.[New](strDefaultWorkspace & "\" & frmWSIn.txtOutFolderName.Text & "\map_document.mxd")
            pMapDoc.ReplaceContents(pMxdContents)
            pMapDoc.SetActiveView(pMxDoc.ActiveView)
            pMapDoc.Save(True, False)
0 Kudos