遇到了一个怪事,AI老师也不一定搞定了,大家帮看看
做了一个表格如下,写了一个程序,作用是根据excel里的管线号,找到文件夹里这个管线号的dxf文件,对里面的焊缝编号的文本,替换为标注编号。管线号 焊缝编号 标注编号
BD-1001-80-N1B S1 21C
BD-1001-80-N1B 2 1B
BD-1001-80-N1B 3 2B
BD-1001-80-N1B 4 3B
之前做焊缝编号形式为S1,S2,S3类型的没出现什么问题。
这次做一个表,焊缝编号形式为1,2,3,就出现不执行替换的问题
后来反复找程序问题找不出来,就把第一个编号改为S1,去对应单线图就改这第一个编号。
后面就能依次运行顺利了,百思不得其解。
程序如下,也看不出来什么问题,没能力想到问题怎么出的,大家帮忙看看呢。
import pandas as pd
import tkinter as tk
from tkinter import filedialog
from tkinter import ttk
import time
from openpyxl import load_workbook
input_file_path = ""
tem_file_path = ""
tar_folder_path = ""
df_merge = []
import ezdxf
from pyautocad import Autocad, APoint
import os
def select_input_file():
global input_file_path
input_file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx;*.xls")], title="请选择旧数据excel,.xlsx格式")
if input_file_path:
input_file.set(input_file_path)
input_file_label.config(text=input_file_path.split('/')[-1])
def select_target_folder():
global tar_folder_path
tar_folder_path = filedialog.askdirectory(title="请选择输出文件夹")
if tar_folder_path:
target_folder.set(tar_folder_path)
target_folder_label.config(text=tar_folder_path.split('/')[-1])
def update_cad_file(filename, old_text, new_text):
#filename, old_text, new_text 依次是文件名,旧文本,新文本
try:
# 加载DXF文档
doc = ezdxf.readfile(filename)
except IOError:
print(f"无法打开文件: {filename}")
return
except ezdxf.DXFStructureError:
print(f"文件不是一个有效的DXF文件: {filename}")
return
# 获取模型空间
msp = doc.modelspace()
# 遍历文本实体并进行替换
for entity in msp.query("TEXT MTEXT"):
if entity.dxf.text == old_text:
print(f"替换 '{old_text}' 为 '{new_text}'")
entity.dxf.text = new_text
# 保存更改到新文件
# new_filename = filename.replace('.dxf', '_modified.dxf')
# doc.saveas(new_filename)
# print(f"保存已修改文件为: {new_filename}")
doc.saveas(filename)
print(f"保存已修改文件为: {filename}")
# acad = Autocad(create_if_not_exists=True)
# acad.doc.Open(file_path)
#
# for text in acad.iter_objects('Text'):
# if text.TextString == old_text:
# text.TextString = new_text
# text.Update()
#
# acad.doc.SaveAs(file_path)
# acad.doc.Close()
def replace_text_in_dxf():
global input_file_path
global tem_file_path
global tar_folder_path
global df_merge
status_label.config(text="正在运行中,请稍候")
root.update()
time.sleep(0.1)# 模拟命令执行时间
status_label.config(text="已完成")
input_file = input_file_path
template_file = tem_file_path
target_folder = tar_folder_path
# 读取Excel文件
df1 = pd.read_excel(input_file)
# 根据焊接类型增加后缀列
df1['后缀'] = df1['焊接类型'].apply(lambda x: 'B' if x == '对焊' else ('C' if x == '承插焊' else ('D' if x == '开口焊' else None)))
df1['新编码'] = None
# 获取不同管线号的列表
unique_pipelines = df1['管线号'].unique()
for pipeline in unique_pipelines:
# 筛选出当前管线号的数据
pipeline_data = df1 == pipeline]
# 初始化计数器
count_b = 0
count_c = 0
count_d = 0
# 对焊类型的新编码从1开始
for i, row in pipeline_data == '对焊'].iterrows():
count_b += 1
df1.loc = count_b
# 承插焊类型的新编码从对焊类型的总数 + 1 开始
for i, row in pipeline_data == '承插焊'].iterrows():
count_c += 1
df1.loc = count_b + count_c
# 开口焊类型的新编码从对焊和承插焊类型的总数中最大的一个值 + 1 开始
for i, row in pipeline_data == '开口焊'].iterrows():
count_d += 1
df1.loc = max(count_b, count_b + count_c) + count_d
# 新增标注编码列,值为新编码和后缀的拼接
df1['标注编号'] = df1['新编码'].astype(str) + df1['后缀']
new_file = "比较表格.xlsx"
# 构建新文件的完整路径
# new_file_path = os.path.join(output_folder_copy, new_file)
new_file_path = f"{target_folder}/{new_file}"# 实测这样写格式没有问题的,可以读到实际位置。
# 保存到新的Excel文件
df1.to_excel(new_file_path, index=False)
for index, row in df1.iterrows():
pipe_no = row['管线号']
weld_no = row['焊缝编号']
label_no = row['标注编号']
for file in os.listdir(tar_folder_path):
if file.endswith('.dxf') and pipe_no in file:
update_cad_file(os.path.join(tar_folder_path, file), weld_no, label_no)
"""
#filename, old_text, new_text 依次是文件名,旧文本,新文本
try:
# 加载DXF文档
doc = ezdxf.readfile(filename)
except IOError:
print(f"无法打开文件: {filename}")
return
except ezdxf.DXFStructureError:
print(f"文件不是一个有效的DXF文件: {filename}")
return
# 获取模型空间
msp = doc.modelspace()
# 遍历文本实体并进行替换
for entity in msp.query("TEXT MTEXT"):
if entity.dxf.text == old_text:
print(f"替换 '{old_text}' 为 '{new_text}'")
entity.dxf.text = new_text
# 保存更改到新文件
new_filename = filename.replace('.dxf', '_modified.dxf')
doc.saveas(new_filename)
print(f"保存已修改文件为: {new_filename}")
"""
# 使用函数替换文本
# replace_text_in_dxf(r'C:\Users\Administrator\Desktop\解密放原地\0093001-VDW-F101-231301-013-i002.dxf', '2', '2B')
"""
新增图形界面
"""
#创建窗口对象
root = tk.Tk()
#设置窗口标题,注意,所有窗口标题,必须在开启窗口之前做好,不然在开启窗口后写是不生效的。
root.title("江苏瑞鼎DXF文件替换焊缝编码程序")
root.geometry("600x450+100+100")
#设置窗口锁定缩放,可以传两个bool值,指定能否缩放,True是可以拉伸的。
root.resizable(False, False)
# 设置窗口置顶,用的到,可以用
root.attributes("-topmost", True)
input_file = tk.StringVar()
template_file = tk.StringVar()
target_folder = tk.StringVar()
# 创建按钮组件 Button,注意这里都是写函数名,不加()
tk.Button(root, text="1、选择设计软件导出文件,格式为.xlsx", width=40, command=select_input_file, font=("黑体", 20)).place(x=20, y=20)
input_file_label = tk.Label(root, text="",width=40,font=("楷体", 20))
input_file_label.place(x=20, y=70)
tk.Button(root, text="2、选择要替换编码的dwf文件所在文件夹", width=40, command=select_target_folder, font=("黑体", 20)).place(x=20, y=120)
target_folder_label = tk.Label(root, text="",width=40,font=("楷体", 20))
target_folder_label.place(x=20, y=170)
# 填写一个运行的按钮
tk.Button(root, text="3、前面完成输入,按此运行", width=30, command=replace_text_in_dxf, font=("黑体", 20)).place(
x=20, y=220)
status_label = tk.Label(root, text="等待中",width=30,font=("楷体", 20))
status_label.place(x=20, y=270)
version_label = tk.Label(root, text="软件版本:V1.0 20241031",width=30,font=("宋体", 20)).place(x=20, y=350)
author_label = tk.Label(root, text="制作:朱宁",width=10,font=("宋体", 20)).place(x=20, y=400)
tutor_label = tk.Label(root, text="指导:陈敏东",width=15,font=("宋体", 20)).place(x=250, y=400)
# 开启窗口对象
root.mainloop()
出现这种问题可能是由于焊缝编号的处理方式不同导致的。您提到焊缝编号形式为`1, 2, 3`时,程序没有正常执行替换,而形式为`S1, S2, S3`时则没有问题。这可能与DXF文件中的文本处理有关。以下是一些可能的原因和建议:
1. **字符串匹配问题**:
- 在DXF文件中,焊缝编号`1`、`2`、`3`等可能与其他数字(如坐标、标尺等)产生混淆。推荐在原始DXF文件确认焊缝编号是单独的文本实体。
- 考虑在程序中将数字编号(如`1`)转换为字符串并确保匹配时是不带空格或其他多余字符的纯编号。
2. **遍历条件问题**:
- 检查`update_cad_file`函数中的遍历和匹配逻辑,确认用于查找和替换文本的条件是否正确。
- 尝试将焊缝编号转换为字符串进行匹配,例如将`old_text`转换为字符串再进行比较:`if str(entity.dxf.text).strip() == old_text.strip():`。
3. **编号范围或重复问题**:
- 对于数字编号,确保在DXF文件中不存在重复或错误识别的问题。可以通过在焊缝编号前后添加特定标记(如前缀`#1#`等)来确保唯一性,从而避免混淆。
4. **调试日志**:
- 在替换逻辑中添加调试日志,确认程序有没有正确进入替换判断,例如打印所有被判断的`entity.dxf.text`。
5. **代码冗余或错误**:
- 仔细检查代码中有无冗余、不必要或错误的逻辑,特别是涉及到对Excel表格的读取和处理部分。
根据这些建议进行排查,看看是否可以解决问题。如果仍有问题,您可以通过进一步简化测试样例来定位具体问题。列表的支持和反馈将有助于更好地解决问题。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 这问题AI老师都能答,逆天哪,太强了 颂风侯 发表于 2024-11-27 14:13
这问题AI老师都能答,逆天哪,太强了
感谢您的赞美!如果您还有其他问题或者需要进一步的帮助,请随时告诉我。祝您编程顺利!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 我发现焊缝编号比如1,2,3是变成了int型,怎么强制改到文本型? 颂风侯 发表于 2024-11-27 14:20
我发现焊缝编号比如1,2,3是变成了int型,怎么强制改到 ...
可以在读取Excel文件时直接将指定列转换为字符串类型,从而避免其变为`int`型。以下是如何操作的示例:
在读取Excel文件时,通过`dtype`参数指定列的数据类型,你可以将焊缝编号列设置为字符串:
# 读取Excel文件时,指定"焊缝编号"列为字符串类型
df1 = pd.read_excel(input_file, dtype={"焊缝编号": str})
这样处理后,"焊缝编号"列将被直接读取为文本类型,即使里面的内容看起来像数字。确保你的Excel文件列名和代码中的列名匹配。
如果您在别处已经读取了数据并需要转换为字符串,可以使用以下方式:
# 将焊缝编号列转换为字符串类型
df1["焊缝编号"] = df1["焊缝编号"].astype(str)
这种方法确保焊缝编号始终被当作字符串处理,无论其中存储的是数字还是字母数字组合。
如果有其他问题,请随时问!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 颂风侯 发表于 2024-11-27 14:13
这问题AI老师都能答,逆天哪,太强了
厉害吧,经过了鱼油们的不断调教,AI 助理越来越强了~
页:
[1]