ArcGIS脚本工具02——批量删除表

一、功能介绍

BatchDeleteTables:批量删除指定工作空间下,用户选中的所有表。

二、实现代码

# -*- coding: utf-8 -*-
import arcpy
import os
import sys

# 重新加载sys以设置默认编码
reload(sys)
sys.setdefaultencoding('utf-8')

# 获取输入参数
input_tables_string = arcpy.GetParameterAsText(0)  # 输入表(多值)
confirm_delete = arcpy.GetParameterAsText(1)       # 确认删除

def batch_delete_tables(table_list, confirm_flag):
    """
    批量删除表的主函数
    """
    
    # 检查确认标志
    if confirm_flag.lower() != 'true':
        return {"status": "cancelled", "message": "未确认删除"}
    
    # 初始化计数器
    deleted_count = 0
    failed_count = 0
    skipped_count = 0
    
    # 设置进度条 - 修复:使用Python 2兼容的字符串格式化
    total_tables = len(table_list)
    progress_msg = "正在删除表... 0/{} 完成".format(total_tables)
    arcpy.SetProgressor("step", progress_msg, 0, total_tables, 1)
    
    # 存储详细结果
    deleted_items = []
    failed_items = []
    skipped_items = []
    
    # 遍历每个表
    for i, table_path in enumerate(table_list, 1):
        try:
            # 清理路径中的空格
            table_path = table_path.strip()
            
            # 更新进度条标签 - 修复:使用Python 2兼容的字符串格式化
            progress_label = "正在处理 {}/{}: {}".format(i, total_tables, os.path.basename(table_path))
            arcpy.SetProgressorLabel(progress_label)
            
            # 检查表是否存在
            if arcpy.Exists(table_path):
                # 获取表信息
                try:
                    desc = arcpy.Describe(table_path)
                    table_name = desc.name
                    data_type = desc.dataType
                    
                    # 验证是否是表类型
                    if desc.dataType not in ["Table", "RelationshipClass", "AttributedRelationshipClass"]:
                        arcpy.AddWarning("  ⚠ {} 不是表类型,跳过 ({})".format(table_name, data_type))
                        skipped_count += 1
                        skipped_items.append({
                            "name": table_name,
                            "path": table_path,
                            "reason": "不是表类型 ({})".format(data_type)
                        })
                        continue
                        
                except Exception as desc_error:
                    table_name = os.path.basename(table_path)
                    data_type = "未知类型"
                    arcpy.AddWarning("  无法获取表信息: {}".format(str(desc_error)))
                
                # 尝试删除表
                arcpy.AddMessage("正在删除: {}".format(table_name))
                
                try:
                    # 删除表
                    arcpy.Delete_management(table_path)
                    
                    # 验证删除结果
                    if not arcpy.Exists(table_path):
                        arcpy.AddMessage("  ✓ 成功删除: {} ({})".format(table_name, data_type))
                        deleted_count += 1
                        deleted_items.append({
                            "name": table_name,
                            "type": data_type,
                            "path": table_path
                        })
                    else:
                        arcpy.AddWarning("  ✗ 删除失败: {} (表仍然存在)".format(table_name))
                        failed_count += 1
                        failed_items.append({
                            "name": table_name,
                            "path": table_path,
                            "reason": "表仍然存在,可能被锁定"
                        })
                except arcpy.ExecuteError as delete_error:
                    # 捕获ArcGIS删除错误
                    error_msg = arcpy.GetMessages(2)
                    arcpy.AddWarning("  ✗ 删除失败: {}".format(table_name))
                    arcpy.AddWarning("    错误信息: {}".format(error_msg))
                    failed_count += 1
                    failed_items.append({
                        "name": table_name,
                        "path": table_path,
                        "reason": "ArcGIS错误: {}".format(error_msg)
                    })
                    
            else:
                arcpy.AddWarning("  ⚠ 表不存在,跳过: {}".format(os.path.basename(table_path)))
                skipped_count += 1
                skipped_items.append({
                    "path": table_path,
                    "reason": "表不存在"
                })
                
        except Exception as e:
            # 捕获其他错误
            arcpy.AddWarning("  ✗ 处理失败: {}".format(os.path.basename(table_path)))
            arcpy.AddWarning("    错误信息: {}".format(str(e)))
            failed_count += 1
            failed_items.append({
                "name": os.path.basename(table_path),
                "path": table_path,
                "reason": "系统错误: {}".format(str(e))
            })
        
        # 更新进度条位置
        arcpy.SetProgressorPosition()
    
    # 重置进度条
    arcpy.ResetProgressor()
    
    # 返回结果
    return {
        "status": "completed",
        "total": total_tables,
        "deleted": deleted_count,
        "failed": failed_count,
        "skipped": skipped_count,
        "deleted_items": deleted_items,
        "failed_items": failed_items,
        "skipped_items": skipped_items
    }


def ValidateInputParameters(table_string, confirm_flag):
    """
    验证输入参数
    """
    
    # 检查确认标志
    if confirm_flag.lower() != 'true':
        return False, [], "操作已取消:未确认删除"
    
    # 检查输入是否为空
    if not table_string or table_string == "#":
        return False, [], "未选择要删除的表"
    
    # 分割字符串为列表
    try:
        table_list = table_string.split(";")
        # 清理列表中的空值和空格
        table_list = [t.strip() for t in table_list if t.strip()]
        
        if len(table_list) == 0:
            return False, [], "未选择有效的表"
            
        return True, table_list, ""
        
    except Exception as e:
        return False, [], "参数解析错误: {}".format(str(e))


def GenerateSummaryReport(result_dict):
    """
    生成删除操作的总结报告
    """
    
    arcpy.AddMessage("=" * 60)
    arcpy.AddMessage("批量删除表操作完成总结")
    arcpy.AddMessage("=" * 60)
    arcpy.AddMessage("总计处理: {} 个表".format(result_dict['total']))
    arcpy.AddMessage("成功删除: {} 个".format(result_dict['deleted']))
    arcpy.AddMessage("删除失败: {} 个".format(result_dict['failed']))
    arcpy.AddMessage("跳过(不存在或不是表): {} 个".format(result_dict['skipped']))
    arcpy.AddMessage("-" * 60)
    
    # 显示失败和跳过的详细信息
    if result_dict['failed'] > 0:
        arcpy.AddWarning("失败的表:")
        for item in result_dict['failed_items']:
            arcpy.AddWarning("  {}: {}".format(item['name'], item['reason']))
    
    if result_dict['skipped'] > 0:
        arcpy.AddMessage("跳过的表:")
        for item in result_dict['skipped_items']:
            arcpy.AddMessage("  {}: {}".format(item['path'], item['reason']))
    
    arcpy.AddMessage("=" * 60)
    
    # 如果所有删除都失败,添加错误信息
    if result_dict['deleted'] == 0 and result_dict['failed'] > 0:
        arcpy.AddError("所有删除操作都失败了,请检查文件权限和锁定状态")


def show_result_dialog(result):
    """显示结果对话框"""
    try:
        # 导入tkinter
        import Tkinter as tk
        import tkMessageBox
        
        # 创建主窗口(隐藏)
        root = tk.Tk()
        root.withdraw()
        
        # 构建消息内容
        message = "批量删除表操作完成!\n\n"
        message += "总计处理: {} 个表\n".format(result['total'])
        message += "成功删除: {} 个\n".format(result['deleted'])
        message += "删除失败: {} 个\n".format(result['failed'])
        message += "跳过(不存在或不是表): {} 个\n".format(result['skipped'])
        
        if result['deleted_items']:
            message += "\n已成功删除的表:\n"
            for item in result['deleted_items']:
                message += "  • {} ({})\n".format(item['name'], item['type'])
        
        if result['failed_items']:
            message += "\n删除失败的表:\n"
            for item in result['failed_items']:
                message += "  • {} - {}\n".format(item['name'], item['reason'])
        
        if result['skipped_items']:
            message += "\n跳过的表:\n"
            for item in result['skipped_items']:
                message += "  • {} - {}\n".format(os.path.basename(item['path']), item['reason'])
        
        message += "\n点击确定关闭对话框。"
        
        # 显示消息框
        tkMessageBox.showinfo("批量删除表完成", message)
        
        # 销毁窗口
        root.destroy()
        
    except ImportError:
        # 如果tkinter不可用,使用控制台输出
        arcpy.AddMessage("注意: 无法显示图形对话框,结果已输出到消息面板。")
    except Exception as e:
        arcpy.AddWarning("显示结果对话框时出错: {}".format(str(e)))


def DoJob():
    """
    主执行函数
    """
    
    try:
        # 1. 验证输入参数
        arcpy.AddMessage("正在验证输入参数...")
        is_valid, table_list, error_msg = ValidateInputParameters(input_tables_string, confirm_delete)
        
        if not is_valid:
            arcpy.AddError(error_msg)
            return
        
        # 2. 显示将要删除的表列表
        arcpy.AddMessage("=" * 60)
        arcpy.AddMessage("将要删除 {} 个表:".format(len(table_list)))
        arcpy.AddMessage("=" * 60)
        
        for i, table_path in enumerate(table_list, 1):
            if arcpy.Exists(table_path):
                try:
                    desc = arcpy.Describe(table_path)
                    arcpy.AddMessage("{}. {} ({})".format(i, desc.name, desc.dataType))
                    arcpy.AddMessage("   路径: {}".format(table_path))
                    
                    # 检查是否为表类型
                    if desc.dataType not in ["Table", "RelationshipClass", "AttributedRelationshipClass"]:
                        arcpy.AddWarning("   警告: 这不是标准表类型!")
                        
                except:
                    arcpy.AddMessage("{}. {}".format(i, os.path.basename(table_path)))
                    arcpy.AddMessage("   路径: {}".format(table_path))
            else:
                arcpy.AddMessage("{}. {} (不存在)".format(i, os.path.basename(table_path)))
                arcpy.AddMessage("   路径: {}".format(table_path))
        
        arcpy.AddMessage("=" * 60)
        arcpy.AddMessage("警告: 此操作不可撤销!")
        
        # 3. 执行批量删除
        arcpy.AddMessage("开始执行批量删除表操作...")
        result = batch_delete_tables(table_list, confirm_delete)
        
        # 4. 生成总结报告
        if result["status"] == "completed":
            GenerateSummaryReport(result)
        elif result["status"] == "cancelled":
            arcpy.AddError(result["message"])
        
        # 6. 完成消息
        arcpy.AddMessage("批量删除表操作执行完成")
        
    except Exception as e:
        arcpy.AddError("执行过程中发生错误: {}".format(str(e)))
        import traceback
        arcpy.AddError(traceback.format_exc())


# 执行
if __name__ == "__main__":
    DoJob()
    

三、参数设置

# 获取输入参数
input_tables_string = arcpy.GetParameterAsText(0)  # 输入表(多值)
confirm_delete = arcpy.GetParameterAsText(1)       # 确认删除

根据功能代码中输入参数的个数和顺序设置交互页面参数。

如上代码所示,BatchDeleteTables有两个输入参数:参数(0),参数(1)。

交互页面设置对应的两个参数:表所在位置;确认删除。

四、功能测试

浏览文件路径,选择待删除的表;勾选确认删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值