Translate python label expression to VB

3945
8
Jump to solution
07-26-2013 08:58 AM
by Anonymous User
Not applicable
First off, I'll admit I do not know much about VB.  A while back I found that there is a bug with exporting maps that have "advanced" python expressions to PDF programmatically (i.e. doing this through arcpy.mapping).  This is not a problem when using VB label expressions.  I have been trying (and failing) to convert the following Python label expression to VB.  This works inside ArcMap but the labels disappear when exported to PDF due to the bug.

def FindLabel ( [DEEDHOLDER] , [PID], [ACRES], [SUM_CSR_Potential], [AVE_CSR] ):   name = " ".join(str( [DEEDHOLDER] ).split(" ")[:5])   # grab only first few words on top line   name2 =  " ".join(str( [DEEDHOLDER] ).split(" ")[5:])  # grab the rest if there are more to wrap to next line   if len(name2) > 1:     name = "\n".join([name,name2])  # join name and name2 vars by a new line   pid =  [PID]    ac =  [ACRES] + " Ac"    sump = "CSR: "+ str(round(float([SUM_CSR_Potential]),1))   ave = "Ave: "+ [AVE_CSR]    return "\n".join([name,pid,ac,sump,ave]) 


This isn't too complicated in Python, but I am unable to successfully convert it to VB.  I would post my attempts at a VB solution, but I would rather save myself the embarrassment. 

If anyone can help, I would appreciate it!  Meanwhile, I will keep trying.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
RichardFairhurst
MVP Honored Contributor
First off, I'll admit I do not know much about VB.  A while back I found that there is a bug with exporting maps that have "advanced" python expressions to PDF programmatically (i.e. doing this through arcpy.mapping).  This is not a problem when using VB label expressions.  I have been trying (and failing) to convert the following Python label expression to VB.  This works inside ArcMap but the labels disappear when exported to PDF due to the bug.

def FindLabel ( [DEEDHOLDER] , [PID], [ACRES], [SUM_CSR_Potential], [AVE_CSR] ):   name = " ".join(str( [DEEDHOLDER] ).split(" ")[:5])   # grab only first few words on top line   name2 =  " ".join(str( [DEEDHOLDER] ).split(" ")[5:])  # grab the rest if there are more to wrap to next line   if len(name2) > 1:     name = "\n".join([name,name2])  # join name and name2 vars by a new line   pid =  [PID]    ac =  [ACRES] + " Ac"    sump = "CSR: "+ str(round(float([SUM_CSR_Potential]),1))   ave = "Ave: "+ [AVE_CSR]    return "\n".join([name,pid,ac,sump,ave]) 


This isn't too complicated in Python, but I am unable to successfully convert it to VB.  I would post my attempts at a VB solution, but I would rather save myself the embarrassment. 

If anyone can help, I would appreciate it!  Meanwhile, I will keep trying.


Here is my attempt:

Function FindLabel ( [DEEDHOLDER] , [PID], [ACRES], [SUM_CSR_Potential], [AVE_CSR] )    Dim MyArray, i, name, pid, ac, sump, ave   MyArray = Split([DEEDHOLDER], " ")    For i = 0 to UBound(MyArray)     if i = 0 Then       name = MyArray(i) ' First word of name.     ElseIf i / 5 <> Round(i / 5, 0) Then       name = name & " " & MyArray(i) ' Add space and word if less than 5 words in line     Else       name = name & vbCrLf & MyArray(i) ' Begin a new line after every 5th word.     End If   Next   pid =  [PID]    ac =  [ACRES] & " Ac"    sump = "CSR: " & str(round(cDbl([SUM_CSR_Potential]),1))   ave = "Ave: " & [AVE_CSR]    FindLabel = name & vbCrLf & pid & vbCrLf & ac & vbCrLf & sump & vbCrLf & ave  End Function

View solution in original post

0 Kudos
8 Replies
RichardFairhurst
MVP Honored Contributor
First off, I'll admit I do not know much about VB.  A while back I found that there is a bug with exporting maps that have "advanced" python expressions to PDF programmatically (i.e. doing this through arcpy.mapping).  This is not a problem when using VB label expressions.  I have been trying (and failing) to convert the following Python label expression to VB.  This works inside ArcMap but the labels disappear when exported to PDF due to the bug.

def FindLabel ( [DEEDHOLDER] , [PID], [ACRES], [SUM_CSR_Potential], [AVE_CSR] ):   name = " ".join(str( [DEEDHOLDER] ).split(" ")[:5])   # grab only first few words on top line   name2 =  " ".join(str( [DEEDHOLDER] ).split(" ")[5:])  # grab the rest if there are more to wrap to next line   if len(name2) > 1:     name = "\n".join([name,name2])  # join name and name2 vars by a new line   pid =  [PID]    ac =  [ACRES] + " Ac"    sump = "CSR: "+ str(round(float([SUM_CSR_Potential]),1))   ave = "Ave: "+ [AVE_CSR]    return "\n".join([name,pid,ac,sump,ave]) 


This isn't too complicated in Python, but I am unable to successfully convert it to VB.  I would post my attempts at a VB solution, but I would rather save myself the embarrassment. 

If anyone can help, I would appreciate it!  Meanwhile, I will keep trying.


Here is my attempt:

Function FindLabel ( [DEEDHOLDER] , [PID], [ACRES], [SUM_CSR_Potential], [AVE_CSR] )    Dim MyArray, i, name, pid, ac, sump, ave   MyArray = Split([DEEDHOLDER], " ")    For i = 0 to UBound(MyArray)     if i = 0 Then       name = MyArray(i) ' First word of name.     ElseIf i / 5 <> Round(i / 5, 0) Then       name = name & " " & MyArray(i) ' Add space and word if less than 5 words in line     Else       name = name & vbCrLf & MyArray(i) ' Begin a new line after every 5th word.     End If   Next   pid =  [PID]    ac =  [ACRES] & " Ac"    sump = "CSR: " & str(round(cDbl([SUM_CSR_Potential]),1))   ave = "Ave: " & [AVE_CSR]    FindLabel = name & vbCrLf & pid & vbCrLf & ac & vbCrLf & sump & vbCrLf & ave  End Function
0 Kudos
by Anonymous User
Not applicable
Thank you Richard!!!  You are the man!  I had to make 2 minor tweaks, but your code was almost flawless.  I would have never figured it out.  Here is what I ended up using:

Function FindLabel ( [DEEDHOLDER] , [PID], [ACRES], [SUM_CSR_Potential], [AVE_CSR] )

  Dim MyArray, i, name, pid, ac, sump, ave
  MyArray = Split([DEEDHOLDER], " ")

  For i = 0 to UBound(MyArray)
    if i = 0 Then
      name = MyArray(i) ' First word of name.
    ElseIf i / 5 <> Round(i / 5, 0) Then
      name = name & " " & MyArray(i) ' Add space and word if less than 5 words in line
    Else
      name = name & vbCrLf & MyArray(i) ' Begin a new line after every 5th word.
    End If
  Next
  pid =  [PID] 
  ac =  [ACRES] & " Ac" 
  sump = "CSR: " & CStr(Round(CSng([SUM_CSR_Potential]),1))
  ave = "Ave: " &  CStr(Round(CSng([AVE_CSR]),1)) 
  FindLabel = name & vbCrLf & pid & vbCrLf & ac & vbCrLf & sump & vbCrLf & ave 
End Function
0 Kudos
ChrisPedrezuela
Occasional Contributor III
Hi guys, ran into this problem yesterday. Is there any other way besides converting to VB expressions?

Cheers
0 Kudos
RichardFairhurst
MVP Honored Contributor
Hi guys, ran into this problem yesterday. Is there any other way besides converting to VB expressions?

Cheers


Edit:  Reread original post and see that there is a bug.  So I guess Python is not an option with the PDF workflow.  JScript is also supposed to be an option, but either way it means a rewrite from Python.  I just happen to be very used to VB Script, so translating most non-spatial code is not too much of a problem for me.
0 Kudos
ChrisPedrezuela
Occasional Contributor III
Yup Im currently using 10.1. I'm working with DDP enabled mxd's that has some layers having label expressions in them that I created using a python parser. what I did was I created another script to batch export a series of DDP maps and when I ran it and checked the output pdf's, those layers with python label expressions are missing labels.
0 Kudos
by Anonymous User
Not applicable
Here is the nimbus for the support incident I logged with Esri regarding the issue:

NIM091502: Labels written in advanced python are not displayed when exported to PDF outside of ArcMap.

Just to echo what Richard already said, I think VB may be the best option if you are exporting PDF's programmatically.  I have had successful exports with some 'advanced python' expressions I have tried, but VB never fails.
0 Kudos
T__WayneWhitley
Frequent Contributor
Thanks Caleb, that answers a question I had today.  I'd further like to note that I was really impressed with how short the Python parser code for a multiline label was, contributed by Matt Sayler here:

http://forums.arcgis.com/threads/92810-Pythn-to-TextWrap#2


I adapted it for use in displaying a legal description (which are typically very long) with this snippet:
from textwrap import fill
def FindLabel([LEGAL1]):
     x = fill([LEGAL1],18)
     return x


What I thought was interesting is that you can adapt some VBScript code (if you absolutely had to) from the Technical Article library here, in the last sample "Stack a label in multiple lines":

HowTo:  Label expression by way of VBScript
http://support.esri.com/en/knowledgebase/techarticles/detail/20154

The behavior for what I was using it for is the rough equivalent adaptation below.  A few of my own comments were added where I had to make a correction to 'skip over' to search for the next break in the attempt to stack lines roughly the same length.  I hesitated to post this code, because I still did not think it is well-written, but I suppose an adequate means to learn VBScript (and is supported by 10.0 and 10.1).  Anyway some of this functionality can likely be taken over by maplex labeling as now this is offered as part of the core product - I did not compare this functionality.  Nice to have options though and in case the index link is needed see this:  http://support.esri.com/en/knowledgebase/techarticles/index

Enjoy,
Wayne

Function FindLabel ( [LEGAL1] )
' Stacks a label in multiple lines if
' exceeding a given length.
' Note: Not applicable to line layers.
' ------------------------------------
  dim s, sNew, i, l
  s = [LEGAL1] 
  l = Len(s)
  if l > 15 then  ' stack if exceeding this length
    sNew = Left(s,15)
    i = 16  ' scan for blank space starting from this position
    While i <= l   'or: Do While
      if Mid(s,i,1) = " " then
        'added:  & Mid(s,i,15)
        sNew = sNew & VBNewLine & Mid(s,i,15)
        'added the following to "skip" i to the next segment
        i = i + 15
      else
        sNew = sNew & Mid(s,i,1)
        'moved the below line inside "end if"
        i = i + 1
      end if
    Wend 'or, coupled with the above "Do While":  Loop
  else
    sNew = s
  end if
 
  FindLabel = sNew
End Function
0 Kudos
ChrisPedrezuela
Occasional Contributor III
Thanks guys. Luckily my python labels were just a stop gap solution. Since my datasets have been updated I wont be needing such advanced label expressions. But it was good to know that this issue exist and the workarounds.

Cheers

Here is the nimbus for the support incident I logged with Esri regarding the issue:

NIM091502: Labels written in advanced python are not displayed when exported to PDF outside of ArcMap.

Just to echo what Richard already said, I think VB may be the best option if you are exporting PDF's programmatically.  I have had successful exports with some 'advanced python' expressions I have tried, but VB never fails.
0 Kudos