In VBA, how do you save a layer file (.lyr) with a relative path?
I have some code that loads a shapefile into ArcMap but I am unsure of how I go about using this shapefile to then save a layer file to disk that has a relative path set.
The idea is after I have run my code and output all the layer files I can move the shapefiles and their associated layer files from a local drive which I use for processing my data to another location where other people can use it.
1 Answer 1
This topic has been discussed before on the ESRI forum, see below.
The issue that you can't go higher in the file hierarchy is really annoying.
But there is a difference when you save the layer via ArcMap:
Make sure that "Store relative path names to data sources" is active.
Rightclick a layer in the TOC, choose "Save as Layer File...") and store the .lyr on your disk.
The Layer is stored in a binary lyr-File. Open the lyr-File with a simple texteditor (e.g. Windows-Notepad).
You can find out the path to the data source stored in the lyr file.
For Example: . . \ . . \ . . \ . . \ d a t a b a s e \ T e s t . g d b
That means that relative from the lyr-File the data source is four folders higher then folder database and there Test.gdb.
If you save the lyr-File with ArcObjects the following path is stored: d a t a b a s e \ T e s t . g d b
It's the incorrect path to datasource.
Why can't I save the lyr-File with the correct relative path to datasource?
I used the following code (C#) to save the lyr-file:
private void saveLyr(string lyrFileName, IFeatureLayer pFLayer)
{
try
{
if (String.IsNullOrEmpty(lyrFileName)) return;
if (pFLayer == null) return;
//Layer ermitteln
IDataLayer2 pDataLayer = pFLayer as IDataLayer2;
IName pname = pDataLayer.DataSourceName;
IDatasetName2 datasetName = pname as IDatasetName2;
IWorkspaceName workspaceName = datasetName.WorkspaceName;
string pathToDB = Path.GetDirectoryName(workspaceName.PathName);
pDataLayer.RelativeBase = pathToDB;
saveToLayerFile(lyrFileName, pDataLayer as ILayer);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void saveToLayerFile(string layerFilePath, ILayer layer)
{
try
{
if (layer == null) return;
//create a new LayerFile instance
ILayerFile layerFile = new LayerFileClass();
//make sure that the layer file name is valid
if (Path.GetExtension(layerFilePath) != ".lyr")
return;
if (layerFile.get_IsPresent(layerFilePath))
File.Delete(layerFilePath);
//create a new layer file
layerFile.New(layerFilePath);
//attach the layer file with the actual layer
layerFile.ReplaceContents(layer);
//save the layer file
layerFile.Save();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}