Files
ctbjrj/tools/project_to_fak.py
T

253 lines
12 KiB
Python

# -*- coding: utf-8 -*-
"""①把 MenuTuhao_AddToFak_Click 的复制逻辑抽成 复制图号到方案库(可复用)
②Click 改为调用 ③新增项目表右键"加入方案库"(整项目) ④挂右键菜单。幂等。"""
import io
import re
P = r"C:\Users\099978\Documents\SharpDevelop Projects\成套报价软件\成套报价软件\主窗口.菜单与库.cs"
s = io.open(P, encoding="utf-8-sig").read()
n = 0
def rep(old, new, tag):
global s, n
if old not in s:
if new in s:
print(tag, "跳过")
return
raise AssertionError(tag + " 缺失: " + old[:70])
s = s.replace(old, new, 1)
n += 1
print(tag, "ok")
# ---- 定位 MenuTuhao_AddToFak_Click 方法体 ----
start_anchor = " private void MenuTuhao_AddToFak_Click(object sender, EventArgs e)"
i0 = s.find(start_anchor)
assert i0 > 0, "AddToFak 方法头缺失"
# 方法结束:其后第一个 \n }\n (8空格闭括号=方法级)
m_end = re.compile(r"\n \}\r?\n").search(s, i0)
end = m_end.end()
body = s[i0:end]
print("AddToFak 方法体长度:", len(body))
# ---- 1) 生成 复制图号到方案库 方法:参数化 _currentTuhao→图号内部ID ----
core = body
# 换方法名与签名
core = core.replace(
" private void MenuTuhao_AddToFak_Click(object sender, EventArgs e)\n {",
" /// <summary>复制一个图号(含箱号/元件子树)从项目库到方案库。供单图号加入与整项目加入共用。</summary>\n"
" private void 复制图号到方案库(string projectId, string 图号内部ID, string srcDbPath, string fakDbPath)\n"
" {", 1)
# 参数化 _currentTuhao
core = core.replace("_currentTuhao", "图号内部ID")
# 删 Click 专属校验段(从开头到 fakDbPath 定义前)
m_fak = re.search(r"(\n\s*string fakDbPath = GetDbFullPath\(@\"sjk\\\\fak\.db\"\);)", core)
if not m_fak:
m_fak = re.search(r"(\n\s*string fakDbPath = GetDbFullPath\(.+fak\.db\"\);)", core)
assert m_fak, "fakDbPath 行未找到"
# ★ 保留新方法签名(否则切割会把它连同校验段一起丢掉)
new_sig = (" /// <summary>复制一个图号(含箱号/元件子树)从项目库到方案库。供单图号加入与整项目加入共用。</summary>\n"
" private void 复制图号到方案库(string projectId, string 图号内部ID, string srcDbPath, string fakDbPath)\n"
" {")
core = new_sig + "\n" + core[m_fak.start(1):] # 签名 + 从 fakDbPath 定义开始保留
# 删尾部 ReloadFakData + MessageBox(调用方负责)
core = re.sub(r"\n\s*// 刷新方案页面的图号表\r?\n\s*ReloadFakData\(\);\r?\n", "\n", core)
core = re.sub(r"\n\s*string msg = \"已把图号[^\r\n]*\r?\n(?:\s+[^\r\n]*\r?\n)*?\s*MessageBox\.Show\(this, msg, \"加入方案库\",[^;]*;\r?\n", "\n", core)
# 内部 xhCount/yjCount 声明保留;统计行保留
new_method = core
# ---- 2) 原 Click 改为调方法 ----
new_click = ''' private void MenuTuhao_AddToFak_Click(object sender, EventArgs e)
{
Log("点击[加入方案库], _currentProjectId=[" + _currentProjectId +
"] _currentTuhao=[" + _currentTuhao + "]");
// 1) 校验当前选中状态
if (string.IsNullOrWhiteSpace(_currentProjectId))
{
MessageBox.Show(this, "请先在项目表中双击选择一个项目,再加入方案库。",
"加入方案库", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (string.IsNullOrWhiteSpace(_currentTuhao))
{
MessageBox.Show(this, "请先在图号表中选择要加入方案库的图号。",
"加入方案库", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 2) 先保存当前三个表的未提交编辑,确保复制到方案库的是最新数据
try { SaveAllQuoteTablesIfDirty(false); }
catch (Exception exSave) { Log("[加入方案库] 预保存失败(继续): " + exSave.Message); }
string srcDbPath = GetQuoteDbPath(_currentProjectId);
if (!System.IO.File.Exists(srcDbPath))
{
MessageBox.Show(this, "项目报价库不存在:\\n" + srcDbPath,
"加入方案库", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
string fakDbPath = GetDbFullPath(@"sjk\\fak.db");
try
{
复制图号到方案库(_currentProjectId, _currentTuhao, srcDbPath, fakDbPath);
Log("[加入方案库] 成功");
ReloadFakData();
MessageBox.Show(this, "已把图号 [" + _currentTuhao + "] 加入方案库。", "加入方案库",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception exAdd)
{
Log("[加入方案库] 失败: " + exAdd);
MessageBox.Show(this, "加入方案库失败:\\n" + exAdd.Message, "加入方案库",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}'''
s = s[:i0] + new_click + "\n" + new_method + s[end:]
n += 1
print("AddToFak 抽方法重构 ok")
# ---- 3) 新增 项目表右键"加入方案库"(整项目) ----
proj_click = '''
/// <summary>项目表右键「加入方案库」:把整个项目(全部图号+箱号+元件+项目信息)复制到方案库。</summary>
private void MenuProject_AddToFak_Click(object sender, EventArgs e)
{
// 取当前选中项目(项目表当前行)
var row = GetFirstSelectedRow(this.advancedDataGridView6);
if (row == null)
{
MessageBox.Show(this, "请先在项目列表中选择要加入方案库的项目。",
"加入方案库", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
string projectId = GetBoundValueAsString(row, "项目编号");
if (string.IsNullOrWhiteSpace(projectId))
{
MessageBox.Show(this, "选中行没有项目编号,无法加入方案库。",
"加入方案库", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
string srcDbPath = GetQuoteDbPath(projectId);
if (!System.IO.File.Exists(srcDbPath))
{
MessageBox.Show(this, "项目报价库不存在:\\n" + srcDbPath,
"加入方案库", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
string fakDbPath = GetDbFullPath(@"sjk\\fak.db");
var sw = System.Diagnostics.Stopwatch.StartNew();
Cursor = Cursors.WaitCursor;
try
{
// 1) 该项目的全部图号(内部ID,按序号顺序)
var 图号们 = new System.Collections.Generic.List<string>();
using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(srcDbPath)))
{
conn.Open();
using (var cmd = new System.Data.SQLite.SQLiteCommand(
"SELECT 内部ID FROM " + TuhaoTableName + " ORDER BY CAST(序号 AS INTEGER);", conn))
using (var r = cmd.ExecuteReader())
while (r.Read())
{
if (!r.IsDBNull(0))
{
string v = r.GetString(0);
if (!string.IsNullOrEmpty(v)) 图号们.Add(v);
}
}
}
if (图号们.Count == 0)
{
MessageBox.Show(this, "项目 [" + projectId + "] 没有图号数据,无法加入方案库。",
"加入方案库", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 2) 逐图号复制到方案库
foreach (var thId in 图号们)
复制图号到方案库(projectId, thId, srcDbPath, fakDbPath);
// 3) 项目信息:该项目库的项目信息行覆盖 fak 的项目信息(项目页客户列显示用)
string projTbl = ProjectInfoTableName;
using (var srcConn = new System.Data.SQLite.SQLiteConnection(GetConnString(srcDbPath)))
using (var dstConn = new System.Data.SQLite.SQLiteConnection(GetConnString(fakDbPath)))
{
srcConn.Open();
dstConn.Open();
var infoRow = new DataTable();
using (var cmd = new System.Data.SQLite.SQLiteCommand(
"SELECT * FROM " + projTbl + " WHERE 项目编号=@id LIMIT 1;", srcConn))
{
cmd.Parameters.AddWithValue("@id", projectId);
using (var ad = new System.Data.SQLite.SQLiteDataAdapter(cmd)) ad.Fill(infoRow);
}
var cols = new System.Collections.Generic.List<string>();
foreach (DataColumn c in infoRow.Columns) cols.Add(c.ColumnName);
using (var tx = dstConn.BeginTransaction())
{
Exec(dstConn, tx, "DELETE FROM " + projTbl + ";");
foreach (DataRow r in infoRow.Rows)
InsertRowByColumns(r, projTbl, cols, dstConn, tx);
tx.Commit();
}
}
sw.Stop();
Log("[加入方案库] 整项目完成: 项目=" + projectId + " 图号=" + 图号们.Count + " 耗时 " + sw.ElapsedMilliseconds + "ms");
ReloadFakData();
MessageBox.Show(this, "已把项目 [" + projectId + "] 加入方案库。\\n共 " + 图号们.Count + " 个图号,耗时 " +
sw.ElapsedMilliseconds + "ms。", "加入方案库",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception exAdd)
{
Log("[加入方案库] 整项目失败: " + exAdd);
MessageBox.Show(this, "加入方案库失败:\\n" + exAdd.Message, "加入方案库",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
Cursor = Cursors.Default;
}
}
/// <summary>Exec 简写(删除表数据用)。</summary>
private static void Exec(System.Data.SQLite.SQLiteConnection conn, System.Data.SQLite.SQLiteTransaction tx, string sql)
{
using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn, tx))
cmd.ExecuteNonQuery();
}
'''
# ---- 插入 proj_click 到 菜单与库.cs(在 复制图号到方案库 方法之前) ----
anchor = " /// <summary>复制一个图号(含箱号/元件子树)从项目库到方案库。供单图号加入与整项目加入共用。</summary>"
print("anchor in s:", anchor in s, "| find:", s.find(anchor)); pos = s.find(anchor)
assert pos > 0, "插入锚缺失"
s = s[:pos] + proj_click + "\n" + s[pos:]
n += 1
print("项目右键方法插入 ok")
# ---- 4) 项目表右键菜单注册(MainForm.cs 挂方案菜单附近)——项目表无右键菜单,新建
p_main = r"C:\Users\099978\Documents\SharpDevelop Projects\成套报价软件\成套报价软件\MainForm.cs"
s4 = io.open(p_main, encoding="utf-8-sig").read()
old4 = ''' // ===== 方案页面(tabPage13)三个表格的联动 ====='''
new4 = ''' // ===== 项目表右键:加入方案库(整项目) =====
var _menuProject = new ContextMenuStrip();
_menuProject.Items.Add("加入方案库", null, MenuProject_AddToFak_Click);
this.advancedDataGridView6.ContextMenuStrip = _menuProject;
Log(" 项目表菜单已挂到 advancedDataGridView6(加入方案库)");
// ===== 方案页面(tabPage13)三个表格的联动 ====='''
assert old4 in s4
io.open(p_main, "w", encoding="utf-8-sig").write(s4.replace(old4, new4, 1))
n += 1
print("右键菜单注册 ok")
io.open(P, "w", encoding="utf-8-sig").write(s)
print("合计", n, "处")