Convert VB to Python, Help?

3387
14
Jump to solution
08-03-2017 05:06 PM
TomMagdaleno
Regular Contributor

Hi all, I am new to Python and trying to make an older piece of code work.  It takes two tables, compares them, and if data in table A doesn't match table B it overwrites A with B. 

If they are equal it leaves them alone...

dim intval

if [STR_NUM] = [SITUS_NR] then

intval = " "

else

intval = [STR_NUM]

end if

If it finds a "nil" in a field in table B it clears the field in table A

dim intval

if [STR_NUM] = "nil" then

intval = " "

else

intval = [SITUS_NR]

end if

Finally it overwrites table A if it finds data in table B

dim intval

if [STR_NUM] <> " " and [STR_NUM] <> "nil" then

intval = [STR_NUM]

else

intval = [SITUS_NR]

end if

Can anyone help me convert these or at least one to Python?

Thank you!

0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Regular Contributor

Per Dan's suggestion, paste the following code into the codeblock (top) section.

def func_shun(a, b):
    the_result = [a, ""][a == b]
    return the_result

In the lower section, paste only the following (I think I have the spelling of your joined tables correct):

func_shun( !asrerror_log_20170803.STR_NUM!, !cam_apn_old.SITUS_NR!)

VB would use square brackets around the field names, but Python uses exclamation marks.  So field calculator is getting confused.  You do have the Python parser selected.  The photo in my post below should help.

View solution in original post

14 Replies
DanPatterson_Retired
MVP Esteemed Contributor

Not applicable for file comparisons but could be implemented as a one-liner (line 11) or turned into a function (using lines 15-) for use within a program or the field calculator

"""
if [STR_NUM] = [SITUS_NR] then
intval = " "
else
intval = [STR_NUM]
end if
"""
# ---- as a field calculator expression or a line of code ----
# for example a = 1, b = 2 or a = 'a', b = 'b'

[" ", a][a == b]  # [False, True][condition check]

# ---- more verbose

if a == b:
    val = " "
else:
    val = a
return val

# ---- more variations exist ----
0 Kudos
TomMagdaleno
Regular Contributor

Ok, I'll try that out Dan.  It is a model builder that uses the field calculator.  I should have clarified that.  I converted this to modelbuilder a few years ago from Avenue, but Avenue still works and VB stopped working.  Go Figure.  With windows 10 probably neither will work so it needs to be in Python now. 

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

avenue to python is a far easier transition syntactically ... have fun

RebeccaStrauch__GISP
MVP Esteemed Contributor

Just for the off-chance that it is VBA and not VB, and if you are using 10.5.x...

At the ArcGIS Desktop 10.5 release, Microsoft Visual Basic for Applications (VBA) Compatibility is no longer included. The VBA Compatibility setup in prior versions can still be installed, but its usage is not supported and may result in software errors or crashes. It is recommended that existing Microsoft VBA users continue to use ArcGIS Desktop version 10.2.2 or earlier, or migrate VBA customizations to ArcMap add-ins, ArcPy scripts, or ArcGIS Pro add-ins built with the Pro SDK for .NET

ArcGIS Desktop 10.5.x system requirements—ArcGIS Help | ArcGIS Desktop 

0 Kudos
TomMagdaleno
Regular Contributor

So this is what I enter in the Field Calculator and I get a syntax error.  I thought maybe it was the colon in the first line but it makes no difference.  Can you spot the error? 

if  !STR_NUM! ==  !SITUS_NR!:
    val = " "
else:
    val =  !STR_NUM!
return val

0 Kudos
ClintonDow1
Occasional Contributor II

Assuming the tables are small enough to be held in memory, you can use set comparisons:

paths = {'table1': r'path\t1', 'table2': r'path\t2'}
sets = map(lambda t: {row for row in arcpy.da.SearchCursor(t, arcpy.ListFields(t))}, paths.values()]
if len(sets[0] - sets[1]) > 0:
   arcpy.management.DeleteRows(paths['table1'])
   arcpy.management.Append(paths['table2'], paths['table1'])‍‍‍‍‍

edit: This compares the entire tables, not row-by-row, I might have misunderstood what you wanted..

DanPatterson_Retired
MVP Esteemed Contributor
def func_shun(a, b):
    """to use... this function goes in the code block
    :  func_shun(!first_field!, !second_field!) ... goes in the expression box
    """    the_result = [a, ""][a == b]  # this is conceptual, replace a and b
    return the_result‍‍‍‍‍‍

your whole code block needs to go in a 'def' and indented 4 lines.

There is a 'code' block, which is where the 'def' goes, then there is an expression box, where the call to the function is made.  In the above example... you would put

func_shun(!STR_NUM!, !SITUS_NR!)  

in the expression box

same line if you fix up your other code block

TomMagdaleno
Regular Contributor

Sorry Dan,

  I think I get what we are trying to do, but I don't know why it isn't working.  See the error below.  This is with joined tables so the A and B names are a lot longer. 

error

0 Kudos
RandyBurton
MVP Regular Contributor

Per Dan's suggestion, paste the following code into the codeblock (top) section.

def func_shun(a, b):
    the_result = [a, ""][a == b]
    return the_result

In the lower section, paste only the following (I think I have the spelling of your joined tables correct):

func_shun( !asrerror_log_20170803.STR_NUM!, !cam_apn_old.SITUS_NR!)

VB would use square brackets around the field names, but Python uses exclamation marks.  So field calculator is getting confused.  You do have the Python parser selected.  The photo in my post below should help.