1

I need to write a Python script to automatically calculate costs into a given column by combining several tables (if possible using ArcPy for ArcMap 10.7) but I’m struggling to do that since I’ve never actually done something like that.

My tables have several columns, but I just listed the ones relevant for my calculations, for simplicity the table names will just be table1, table2, table3. Unfortunately, I don’t have any dummy data that I could post here.

My tables:

  • Table1, Columns: area(int), number(string), code(int), section(string)
  • Table2, Columns : code(int), a_value(double)
  • Table3, Columns : number(string), b _value(double),costs_calc(double)

Table1 and Table2 are connected via the ID in the respective column «code» ; Table1 and Table3 are connected via the number in the respective column «number»

Goal : script should automatically calculate costs in column «costs_calc» from values stored in 3 different tables.

Process I want to script (or how I figured the steps to get a result look like):

Step 1: Filter in Table1, from column « section » all rows with the value «B» (only those rows with this value are needed for further calculation, the other rows should not be included)

Step 2: Multiply Values in «a_value» (Table2) with all values from «area» (Table1) (for all rows filtered in Step 1 – of course Step 1 and Step 2 can be swaped if it’s easier (not sure)) --Interim results could be written into a temporary table or into a new column (costs_interim) in table1 – whatever is easier…

Step 3: Summarize the result calculated in Step 2 according to their number (Table1) (here I want all the calculated results combined/summarized according to their number -- after calculation there are for example 5 results for number 12345 (because their «code» is different) and these should be summarized into) interim results could be written into a temporary table or a new column in table3

Example for what I mean with "summarize calculated interim results (costs_interim) according to number", that's what should happen: enter image description here enter image description here

Step 4: Results calculated in Step 3 (summarized values) should be multiplied with the values in column « b_value ». The results of this step will also be the final results and are thus written into the column «costs_calc» (Table3)

I know I can execute the first step by using the SearchCursor(arcpy)function but beyond that, I’m lost.

Hence I also have no code up to now except for import arcpy, math, etc. and setting the environment and a first try with the SearchCursor-function..

my first try:

fc="table1" 
fields = ['section','area']  
delimfield = arcpy.AddFieldDelimiters(fc, fields[1]) 
cursor = arcpy.da.SearchCursor(fc, fields, delimfield +"= 'B'")

#Open a searchcursor
rows = arcpy.SearchCursor("c:/Users/myuser/mydatabase/table1",
                          fields="section")

#Iterate through the rows in the cursor and print out the section value.
    for row in rows:
        print("section: {0}".format(
            row.getValue("B")))

I've also added the mentioned steps as followed into the code:

# Local variables:
table1 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table1"
table2 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table2"
table3 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table3"
table1_a = table1
table1_b = table1_a
table1_c = table1_b
table1_d = table1_c
table1_e = table1_d
table3_a = table3
table1_end = table1_e

# Process: Add field in table1 for interim results
arcpy.AddField_management(talbe1, "costs_interim", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Join table1 and table2 via shared fields "code"
arcpy.JoinField_management(table_b, "code", table2, "code", "")

# Process: calculate field costs_interim
arcpy.CalculateField_management(table1_c, "costs_interim", "!area!* !a_value!", "")

# Process: add field in table3
arcpy.AddField_management(table3, "costs_calc_interim", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: join table1 and table3 via shared field "number"
arcpy.JoinField_management(table1_d, "number", table3_a, "number", "")

# Process: calculate endresult into field "cost_calc"
arcpy.CalculateField_management(table1_e, "costs_calc", "!costs_calc_interim! * !b_value! / 100", "")

The things here is, that I add new columns (which is ok) but with every join or calculation a new table gets generated. I'd prefer the tables to be generated temporarily, so that the final result is not in a new table but written into table3 as described in the intro.

What is still missing, is how to summarize the calculated field "costs__interim" according to their value in the field/column "number" before joining the tables in the step afterwards.

And how to integrate the filter with the first calculation (aso to only calculate the filtered options and ommit the others)

5
  • What happened when you ran the code that you’ve presented?
    – PolyGeo
    Commented Jun 15, 2022 at 10:08
  • 1
    I think you should use arcpy.da cursors instead of the old style.
    – PolyGeo
    Commented Jun 15, 2022 at 10:09
  • thank you for the hint @PolyGeo, I'll try it and let you know! Getting the filter to work would be a nice first step
    – geofreak
    Commented Jun 15, 2022 at 11:59
  • Will the filter be applied once with a single value, or is the filtering iterative with different values over time? I ask because if the latter, then it might make sense to not filter and all and group the data instead by the values.
    – bixb0012
    Commented Jun 16, 2022 at 13:19
  • @bix0012 in this case, the calcuation should only be made for rows with that specific value and ignore all other values (it's to generate a report in a later step which only concerns rows with the said value). As far as I know there's no changes in that for the future, that's why I though of filtering it. But your idea of grouping the data might actually be a good one as well, thank you!
    – geofreak
    Commented Jun 17, 2022 at 6:21

1 Answer 1

-1

Update: Instead of arcpy.da.SearchCursor() I used arcpy.TableSelect afterwards as mentioned already in the questions just adding fields (arcpy.AddField) and joining (arcpy.JoinField), as well as the summary statistics (finally seems to work as well). Once I test it and confirm it's running, I'll post the final code.

Still open for any inputs or ideas though

Working code (just the part for answering the question):

# local variables (generated temporarily)
tab1_2 = tab1

tab2 = workspace + '\\' + "costs_temp.gdb" + '\\' + "tab2_temp"
tab2_temp__2_ = tab2_temp
tab2_temp__3_ = tab2_temp__2_
tab2_temp__4_ = tab2_temp__3_

tab1__3_ = tab1__2_
tab1__4_ = tab1__3_

AVS_BBART = db + '\\' + "\\AVS_BBART"

tab2_SUM = workspace + '\\' + "cost_temp.gdb" + '\\' + "TAB2_SUM"


try:
# Calculation process
    arcpy.AddMessage('Starting calculation process ...')
# for column "sektion" select all rows with value "B" in table "avrpt_libeschrieb"
    arcpy.TableSelect_analysis(tab2, tab2_temp, "SEKTION = 'B'")
    arcpy.AddMessage('Filter table: ok')
# add a temporary field for later calculation results to table avrpt_libeschrieb
    arcpy.AddField_management(tab2, "costs_interim", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
# join fields from table avrpt_libeschrieb with table avs_bbart on art=code for later calculation over both tables
    arcpy.JoinField_management(tab2_temp__2_, "ART", AVS_BBART, "CODE", "CODE;a_cvalue")
    arcpy.AddMessage('join tables in temporary gdb: ok')
# calculate field from values of joined tables into newly added field
    arcpy.CalculateField_management(tab2_temp__3_, "costs_interim", "!area!* !a_value!", "PYTHON", "")
    arcpy.AddMessage('temporary calculations: ok')
# summary statistics to merge all results according to their number
    arcpy.Statistics_analysis(tab2_temp__4_, tab2_SUM, "costs_interim SUM", "NUMBER")
    arcpy.AddMessage('summarize fields: ok')
# join fields from tables fpr avrpt_libeschrieb on av_liegezentroid on number=number
    arcpy.JoinField_management(tab1__2_, "NUMBER", tab2_SUM, "NUMBER", "NUMBER;SUM_costs_interim")
    arcpy.AddMessage('join tables: ok')
# add field for results
    arcpy.AddField_management(tab1__3_, "costs_calc_interim", "DOUBLE", "", "", "", "", "NULLABLE", "", "")
    arcpy.AddMessage('field added')
# calculate field
    arcpy.CalculateField_management(table1_e, "costs_calc", "!costs_calc_interim! * !b_value! / 100", "")
    arcpy.AddMessage('interim results calculated')
# calculate endresult rounded
    arcpy.CalculateField_management(tab1__4_, "costs_calc", "math.ceil(!costs_calc_interim!)", "PYTHON", "")
    arcpy.AddMessage('...calculation process finished without errors')
except Exception,e:
    arcpy.AddMessage('Something went wrong. Please try again')
    arcpy.AddMessage("Fehler: " + str(e))
1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Jun 21, 2022 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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