0

Context:

Using ArcGIS 10.3, Python 2.7.8.

I have x .shp and y .lyr files. I am trying to loop through the shapefiles folder and the lyr folder and to create x * y .mxds that each contains one shapefile and one .lyr file.

Code:

import os 
import arcpy

workspace = os.getcwd()

lyrFolder = workspace + '\\Lyr\\' 
shpFolder = workspace + '\\Shp\\'

mxd = arcpy.mapping.MapDocument(workspace + 'empty.mxd') 
dataFrame = arcpy.mapping.ListDataFrames(mxd,"*")[0]

for shapefile in os.listdir(shpFolder):
  if shapefile.endswith(".shp"):
    shpLayer = arcpy.mapping.Layer(shpFolder + shapefile)
    arcpy.mapping.AddLayer(dataFrame,shpLayer)
    shpName = shpLayer.name

    for lyrFile in os.listdir(lyrFolder):
      if lyrFile.endswith(".lyr"):
        lyrLayer = arcpy.mapping.Layer(lyrFolder + lyrFile)
        arcpy.mapping.AddLayer(dataFrame,lyrLayer)
        lyrName = lyrLayer.name

        mxdName = shpName + "_" + lyrName
        mxd.saveACopy(mxdDir + mxdName + '.mxd')

Expected result:

I expected to create the map documents, each one containing 1 shapefile and 1 layer file, as suggested with this minimal example:

shapefiles = [shp1, shp2]
layerfiles = [lyr1, lyr2, lyr3, lyr4]

mxd = [mxd1, mxd2, mxd3, mxd4, mxd5, mxd6, mxd7, mxd8]

mxd1 = shp1 + lyr1
mxd2 = shp1 + lyr2
mxd3 = shp1 + lyr3
mxd4 = shp1 + lyr4

mxd5 = shp2 + lyr1
mxd6 = shp2 + lyr2
mxd7 = shp2 + lyr3
mxd8 = shp2 + lyr4

Current result:

The problem is that each time a new document is created, the previous file is also added, as below:

mxd1 = shp1 + lyr1
mxd2 = shp1 + lyr1 + lyr2
mxd3 = shp1 + lyr1 + lyr2 + lyr3
mxd4 = shp1 + lyr1 + lyr2 + lyr3 + lyr4

mxd5 = shp1 + shp2 + lyr1
mxd6 = shp1 + shp2 + lyr1 + lyr2
mxd7 = shp1 + shp2 + lyr1 + lyr2 + lyr3
mxd8 = shp1 + shp2 + lyr1 + lyr2 + lyr3 + lyr4

I have tried adding os.system("TASKKILL /F /IM ArcMap.exe") at the end of the second loop, but this only seems to solve the problem with the shapefiles: every new document is created with a single shapefile, but the lyr files still pile up till the last mxd.

  • Move your mxd and dataFrame variables inside the second for loop. – fatih_dur Apr 15 '18 at 4:29
2

You have to remove previous shp layer in its own loop end, and lyr layer in its own loop end, after saving mxd.

(I used glob module. It gives full path of files matched given pattern)

import os
import arcpy
from glob import glob

workspace = os.getcwd()

lyrFolder = workspace + '/Lyr/' 
shpFolder = workspace + '/Shp/'

mxd = arcpy.mapping.MapDocument(workspace + 'empty.mxd') 
dataFrame = arcpy.mapping.ListDataFrames(mxd,"*")[0]

shapefiles = glob(shpFolder + '*.shp') # [shp1_path, shp2_path, 0...]
lyr_files = glob(lyrFolder + '*.lyr')  # [lyr1_path, lyr2_path, 0...]

for shapefile in shapefiles:
    shpLayer = arcpy.mapping.Layer(shapefile)
    arcpy.mapping.AddLayer(dataFrame, shpLayer)
    shpName = shpLayer.name

    for lyr_file in lyr_files:
        lyrLayer = arcpy.mapping.Layer(lyr_file)
        arcpy.mapping.AddLayer(dataFrame,lyrLayer)
        lyrName = lyrLayer.name

        mxdName = shpName + "_" + lyrName
        mxd.saveACopy(mxdDir + mxdName + '.mxd')

        arcpy.mapping.RemoveLayer(dataFrame, lyrLayer) #######

    arcpy.mapping.RemoveLayer(dataFrame, shpLayer) #######

Try that code. I didn't run all code myself. You may need small changes.

  • Is there any reason to use glob rather than arcpy.da.Walk here? If I can get away with only importing one site package rather than multiple modules I try to. – PolyGeo Apr 14 '18 at 21:48
  • 1
    No, Just habits. I like glob module. – Kadir Şahbaz Apr 14 '18 at 21:52
  • I still upvoted. I asked because I suspect those new to ArcPy will find its da.Walk easier to learn than glob. – PolyGeo Apr 14 '18 at 21:56
  • 1
    @PolyGeo, But, yes. arcpy.da.Walk is frequently more sensible. – Kadir Şahbaz Apr 14 '18 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.