鱼C论坛

 找回密码
 立即注册
查看: 483|回复: 8

[已解决]遇到了一个怪事,AI老师也不一定搞定了,大家帮看看

[复制链接]
发表于 2024-11-27 14:03:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
做了一个表格如下,写了一个程序,作用是根据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,去对应单线图就改这第一个编号。
后面就能依次运行顺利了,百思不得其解。
程序如下,也看不出来什么问题,没能力想到问题怎么出的,大家帮忙看看呢。

  1. import pandas as pd
  2. import tkinter as tk
  3. from tkinter import filedialog
  4. from tkinter import ttk
  5. import time
  6. from openpyxl import load_workbook
  7. input_file_path = ""
  8. tem_file_path = ""
  9. tar_folder_path = ""
  10. df_merge = []
  11. import ezdxf
  12. from pyautocad import Autocad, APoint
  13. import os

  14. def select_input_file():
  15.     global input_file_path
  16.     input_file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx;*.xls")], title="请选择旧数据excel,.xlsx格式")
  17.     if input_file_path:
  18.         input_file.set(input_file_path)
  19.         input_file_label.config(text=input_file_path.split('/')[-1])

  20. def select_target_folder():
  21.     global tar_folder_path
  22.     tar_folder_path = filedialog.askdirectory(title="请选择输出文件夹")
  23.     if tar_folder_path:
  24.         target_folder.set(tar_folder_path)
  25.         target_folder_label.config(text=tar_folder_path.split('/')[-1])


  26. def update_cad_file(filename, old_text, new_text):

  27.     #filename, old_text, new_text 依次是文件名,旧文本,新文本
  28.     try:
  29.     # 加载DXF文档
  30.         doc = ezdxf.readfile(filename)
  31.     except IOError:
  32.         print(f"无法打开文件: {filename}")
  33.         return
  34.     except ezdxf.DXFStructureError:
  35.         print(f"文件不是一个有效的DXF文件: {filename}")
  36.         return

  37.     # 获取模型空间
  38.     msp = doc.modelspace()

  39.     # 遍历文本实体并进行替换
  40.     for entity in msp.query("TEXT MTEXT"):
  41.         if entity.dxf.text == old_text:
  42.             print(f"替换 '{old_text}' 为 '{new_text}'")
  43.             entity.dxf.text = new_text

  44.     # 保存更改到新文件
  45.     # new_filename = filename.replace('.dxf', '_modified.dxf')
  46.     # doc.saveas(new_filename)
  47.     # print(f"保存已修改文件为: {new_filename}")
  48.     doc.saveas(filename)
  49.     print(f"保存已修改文件为: {filename}")

  50.     # acad = Autocad(create_if_not_exists=True)
  51.     # acad.doc.Open(file_path)
  52.     #
  53.     # for text in acad.iter_objects('Text'):
  54.     #     if text.TextString == old_text:
  55.     #         text.TextString = new_text
  56.     #         text.Update()
  57.     #
  58.     # acad.doc.SaveAs(file_path)
  59.     # acad.doc.Close()


  60. def replace_text_in_dxf():
  61.     global input_file_path
  62.     global tem_file_path
  63.     global tar_folder_path
  64.     global df_merge
  65.     status_label.config(text="正在运行中,请稍候")
  66.     root.update()
  67.     time.sleep(0.1)  # 模拟命令执行时间
  68.     status_label.config(text="已完成")

  69.     input_file = input_file_path
  70.     template_file = tem_file_path
  71.     target_folder = tar_folder_path

  72.     # 读取Excel文件
  73.     df1 = pd.read_excel(input_file)
  74.     # 根据焊接类型增加后缀列
  75.     df1['后缀'] = df1['焊接类型'].apply(lambda x: 'B' if x == '对焊' else ('C' if x == '承插焊' else ('D' if x == '开口焊' else None)))
  76.     df1['新编码'] = None

  77.     # 获取不同管线号的列表
  78.     unique_pipelines = df1['管线号'].unique()
  79.     for pipeline in unique_pipelines:
  80.         # 筛选出当前管线号的数据
  81.         pipeline_data = df1[df1['管线号'] == pipeline]
  82.         # 初始化计数器
  83.         count_b = 0
  84.         count_c = 0
  85.         count_d = 0

  86.         # 对焊类型的新编码从1开始
  87.         for i, row in pipeline_data[pipeline_data['焊接类型'] == '对焊'].iterrows():
  88.             count_b += 1
  89.             df1.loc[i, '新编码'] = count_b

  90.         # 承插焊类型的新编码从对焊类型的总数 + 1 开始
  91.         for i, row in pipeline_data[pipeline_data['焊接类型'] == '承插焊'].iterrows():
  92.             count_c += 1
  93.             df1.loc[i, '新编码'] = count_b + count_c

  94.         # 开口焊类型的新编码从对焊和承插焊类型的总数中最大的一个值 + 1 开始
  95.         for i, row in pipeline_data[pipeline_data['焊接类型'] == '开口焊'].iterrows():
  96.             count_d += 1
  97.             df1.loc[i, '新编码'] = max(count_b, count_b + count_c) + count_d

  98.     # 新增标注编码列,值为新编码和后缀的拼接
  99.     df1['标注编号'] = df1['新编码'].astype(str) + df1['后缀']

  100.     new_file = "比较表格.xlsx"
  101.     # 构建新文件的完整路径
  102.     # new_file_path = os.path.join(output_folder_copy, new_file)
  103.     new_file_path = f"{target_folder}/{new_file}"  # 实测这样写格式没有问题的,可以读到实际位置。

  104.     # 保存到新的Excel文件
  105.     df1.to_excel(new_file_path, index=False)

  106.     for index, row in df1.iterrows():
  107.         pipe_no = row['管线号']
  108.         weld_no = row['焊缝编号']
  109.         label_no = row['标注编号']

  110.         for file in os.listdir(tar_folder_path):
  111.             if file.endswith('.dxf') and pipe_no in file:
  112.                 update_cad_file(os.path.join(tar_folder_path, file), weld_no, label_no)

  113.     """
  114.     #filename, old_text, new_text 依次是文件名,旧文本,新文本
  115.     try:
  116.     # 加载DXF文档
  117.         doc = ezdxf.readfile(filename)
  118.     except IOError:
  119.         print(f"无法打开文件: {filename}")
  120.         return
  121.     except ezdxf.DXFStructureError:
  122.         print(f"文件不是一个有效的DXF文件: {filename}")
  123.         return

  124. # 获取模型空间
  125.     msp = doc.modelspace()

  126. # 遍历文本实体并进行替换
  127.     for entity in msp.query("TEXT MTEXT"):
  128.         if entity.dxf.text == old_text:
  129.             print(f"替换 '{old_text}' 为 '{new_text}'")
  130.             entity.dxf.text = new_text

  131. # 保存更改到新文件
  132.     new_filename = filename.replace('.dxf', '_modified.dxf')
  133.     doc.saveas(new_filename)
  134.     print(f"保存已修改文件为: {new_filename}")
  135.     """

  136. # 使用函数替换文本
  137. # replace_text_in_dxf(r'C:\Users\Administrator\Desktop\解密放原地\0093001-VDW-F101-231301-013-i002.dxf', '2', '2B')


  138. """
  139. 新增图形界面
  140. """
  141. #创建窗口对象
  142. root = tk.Tk()
  143. #设置窗口标题,注意,所有窗口标题,必须在开启窗口之前做好,不然在开启窗口后写是不生效的。
  144. root.title("江苏瑞鼎DXF文件替换焊缝编码程序")
  145. root.geometry("600x450+100+100")
  146. #设置窗口锁定缩放,可以传两个bool值,指定能否缩放,True是可以拉伸的。
  147. root.resizable(False, False)
  148. # 设置窗口置顶,用的到,可以用
  149. root.attributes("-topmost", True)

  150. input_file = tk.StringVar()
  151. template_file = tk.StringVar()
  152. target_folder = tk.StringVar()


  153. # 创建按钮组件 Button,注意这里都是写函数名,不加()
  154. tk.Button(root, text="1、选择设计软件导出文件,格式为.xlsx", width=40, command=select_input_file, font=("黑体", 20)).place(x=20, y=20)
  155. input_file_label = tk.Label(root, text="",width=40,font=("楷体", 20))
  156. input_file_label.place(x=20, y=70)

  157. tk.Button(root, text="2、选择要替换编码的dwf文件所在文件夹", width=40, command=select_target_folder, font=("黑体", 20)).place(x=20, y=120)
  158. target_folder_label = tk.Label(root, text="",width=40,font=("楷体", 20))
  159. target_folder_label.place(x=20, y=170)

  160. # 填写一个运行的按钮
  161. tk.Button(root, text="3、前面完成输入,按此运行", width=30, command=replace_text_in_dxf, font=("黑体", 20)).place(
  162.         x=20, y=220)

  163. status_label = tk.Label(root, text="等待中",width=30,font=("楷体", 20))
  164. status_label.place(x=20, y=270)

  165. version_label = tk.Label(root, text="软件版本:V1.0 20241031",width=30,font=("宋体", 20)).place(x=20, y=350)
  166. author_label = tk.Label(root, text="制作:朱宁",width=10,font=("宋体", 20)).place(x=20, y=400)
  167. tutor_label = tk.Label(root, text="指导:陈敏东",width=15,font=("宋体", 20)).place(x=250, y=400)

  168. # 开启窗口对象
  169. root.mainloop()
复制代码

最佳答案
2024-11-27 14:20:30
颂风侯 发表于 2024-11-27 14:20
我发现焊缝编号比如1,2,3是变成了int型,怎么强制改到 ...


可以在读取Excel文件时直接将指定列转换为字符串类型,从而避免其变为`int`型。以下是如何操作的示例:

在读取Excel文件时,通过`dtype`参数指定列的数据类型,你可以将焊缝编号列设置为字符串:

  1. # 读取Excel文件时,指定"焊缝编号"列为字符串类型
  2. df1 = pd.read_excel(input_file, dtype={"焊缝编号": str})
复制代码


这样处理后,"焊缝编号"列将被直接读取为文本类型,即使里面的内容看起来像数字。确保你的Excel文件列名和代码中的列名匹配。

如果您在别处已经读取了数据并需要转换为字符串,可以使用以下方式:

  1. # 将焊缝编号列转换为字符串类型
  2. df1["焊缝编号"] = df1["焊缝编号"].astype(str)
复制代码


这种方法确保焊缝编号始终被当作字符串处理,无论其中存储的是数字还是字母数字组合。

如果有其他问题,请随时问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 14:03:52 | 显示全部楼层
出现这种问题可能是由于焊缝编号的处理方式不同导致的。您提到焊缝编号形式为`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 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-11-27 14:13:29 | 显示全部楼层
这问题AI老师都能答,逆天哪,太强了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-27 14:13:41 | 显示全部楼层
颂风侯 发表于 2024-11-27 14:13
这问题AI老师都能答,逆天哪,太强了


感谢您的赞美!如果您还有其他问题或者需要进一步的帮助,请随时告诉我。祝您编程顺利!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-11-27 14:20:13 | 显示全部楼层
我发现焊缝编号比如1,2,3是变成了int型,怎么强制改到文本型?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-27 14:20:30 | 显示全部楼层    本楼为最佳答案   
颂风侯 发表于 2024-11-27 14:20
我发现焊缝编号比如1,2,3是变成了int型,怎么强制改到 ...


可以在读取Excel文件时直接将指定列转换为字符串类型,从而避免其变为`int`型。以下是如何操作的示例:

在读取Excel文件时,通过`dtype`参数指定列的数据类型,你可以将焊缝编号列设置为字符串:

  1. # 读取Excel文件时,指定"焊缝编号"列为字符串类型
  2. df1 = pd.read_excel(input_file, dtype={"焊缝编号": str})
复制代码


这样处理后,"焊缝编号"列将被直接读取为文本类型,即使里面的内容看起来像数字。确保你的Excel文件列名和代码中的列名匹配。

如果您在别处已经读取了数据并需要转换为字符串,可以使用以下方式:

  1. # 将焊缝编号列转换为字符串类型
  2. df1["焊缝编号"] = df1["焊缝编号"].astype(str)
复制代码


这种方法确保焊缝编号始终被当作字符串处理,无论其中存储的是数字还是字母数字组合。

如果有其他问题,请随时问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-27 15:24:18 | 显示全部楼层
颂风侯 发表于 2024-11-27 14:13
这问题AI老师都能答,逆天哪,太强了

厉害吧,经过了鱼油们的不断调教,AI 助理越来越强了~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-12-24 10:26:04 | 显示全部楼层
小甲鱼的二师兄 发表于 2024-11-27 15:24
厉害吧,经过了鱼油们的不断调教,AI 助理越来越强了~

神一样的ai,遇事不决问ai现在我是这样啦,现在哪个ai更强点?编程辅导方面,还是都差不多的,chatgpt我没用过,文心一言,豆包,kimi,讯飞都用过,讯飞还是买的鼠标,现在感觉讯飞的最烂,速度慢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-12-25 06:06:36 From FishC Mobile | 显示全部楼层
这个AI都能答!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-6 07:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表