Gs_Class.Gs_DataFunction数据操作类库20160225

本文介绍了一系列在C#中高效处理数据的方法,包括数据库交互、数据格式转换、数据复制等关键技术点,提供了多种场景下的解决方案。

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
//
using System.IO;
using System.Data.OleDb;
using System.Data.Common;
using System.Management; //添加引用
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;

namespace Gs_Class
{
public partial class gsDataFunction : Gs_DataFunction { }; //换个名好输入
public partial class Gs_DataFunction //: System.Web.UI.Page
{
public static bool DebugMode = false; //调试状态
public const int nXor = 5; //异或值
public const int nDefaultSessionTimeOut = 60; //默认超时
public static string default_Direct = "~/default.aspx";
public static string zhCN_Direct = "~/zh-CN/Login.aspx";
public static string enGB_Direct = "~/en-GB/Login.aspx";
public static string sConnectionString = "";


#region//下载文件,runDownLoad
protected static bool runDownLoad(HttpResponse Response, string fileName)
{
bool lResult = false;
try
{
if (!System.IO.File.Exists(fileName)) throw new Exception("Can not find this file!");
FileInfo file = new System.IO.FileInfo(fileName);
//
Response.Clear();
//设置输出流的HTPP字符集,确定字符的编码格式
Response.Charset = "utf-8";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
//Response.ContentEncoding = System.Text.Encoding.UTF8;
//下载attachment 参数表示作为附件下载,可以改成online在线打开。添加头信息,为"文件下载/另存为"对话框指定默认文件名
Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(file.Name));
// 添加头信息,指定文件大小,让浏览器能够显示下载进度
// Response.AddHeader("Content-Length", file.Length.ToString());
// 指定返回的是一个不能被客户端读取的流,必须被下载
Response.ContentType = "application/ms-word";
//this.EnableViewState = false;
Response.Filter.Close();
// 把文件流发送到客户端
Response.WriteFile(file.FullName);
// 停止页面的执行
Response.End();
lResult = true;
}
catch (Exception x)
{
throw new Exception("runDownload Error:" + x.Message);
}
finally
{
}
return lResult;
}
#endregion

#region//在GridView中根据字段查找列,findColumnByField。列必须是绑定列
/// <summary>
/// 在GridView中根据字段查找列,列必须是绑定列、超链接列 findColumnByField
/// </summary>
/// <param name="grd"></param>
/// <param name="sField"></param>
/// <returns></returns>
public static int findColumnByField(GridView grd, string sField)
{ //根据字段查找列
int result = -1;
int i = 0;
object obj = null;
for (i = 0; i < grd.Columns.Count; i++)
{
obj = grd.Columns[i];
if (!(obj is BoundField || obj is HyperLinkField)) continue;
//
if (obj is BoundField && (obj as BoundField).DataField.ToUpper() == sField.ToUpper()) return i;
if (obj is HyperLinkField && (obj as HyperLinkField).DataTextField.ToUpper() == sField.ToUpper()) return i;
}
return result;
}
public static DataControlField findColumnByFieldA(GridView grd, string sField)
{ //根据字段查找列 BoundField DataControlField
int n = findColumnByField(grd, sField);
if (n < 0) return null; else return grd.Columns[n];
}
#endregion

#region//生成新编号,buildNewID
/// <summary>
/// 生成新编号,以OleDbConnection作为参数注意:如果connection启动了事务,会返回DataReader错误。
/// </summary>
public static string buildNewID(string sTable, string sIDHead, int nIDLen, string sKeyField, OleDbConnection connection)
{
return buildNewID(sTable, sIDHead, nIDLen, sKeyField, "", connection);
}
public static string buildNewID(string sTable, string sIDHead, int nIDLen, string sKeyField, string sAddinFilter, OleDbConnection connection)
{
OleDbConnection conn = connection;
if (conn == null) conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]);
OleDbCommand cmd = new OleDbCommand("", conn);
return buildNewID(sTable, sIDHead, nIDLen, sKeyField, sAddinFilter, cmd);
}
/// <summary>
/// 生成新编号,以OleDbCommand作为参数,便于统一事务,注意:传入Command之前,请显式关闭基于此Command的DataReader,否则会出DataReader错误
/// </summary>
public static string buildNewID(string sTable, string sIDHead, int nIDLen, string sKeyField, OleDbCommand command)
{
return buildNewID(sTable, sIDHead, nIDLen, sKeyField, "", command);
}
public static string buildNewID(string sTable, string sIDHead, int nIDLen, string sKeyField, string sAddinFilter, OleDbCommand command)
{
return buildNewID(sTable, sIDHead, nIDLen, sKeyField, "", false, command);
}
/// <summary>
/// 生成新编号。从数据表中查出Top 1符合条件的值,+1
/// 编号生成规则有3种:纯数字,前导0的数字,有编号头的:
/// * 纯数字:用dbo.isNumber函数检查
/// * 有编号头的:有头则like头,
/// * 没有编号头就是数字前导0,只判断首字母。
/// </summary>
/// <param name="sTable">要查找的表</param>
/// <param name="sIDHead">编号头</param>
/// <param name="nIDLen">编号长度</param>
/// <param name="sKeyField">关键字段,为空则默认为“sID”</param>
/// <param name="sAddinFilter">附加查询条件</param>
/// <param name="lIdIsNumber">此编号是纯数字,会将关键字转为Numeric来排序。是否纯数字通过dbo.isNumber函数判断,所以数据库必须有此函数</param>
/// <param name="command">通过此command执行,类似delphi的TAdoQuery,可以带事务</param>
/// <returns>返回字符串</returns>
public static string buildNewID(string sTable, string sIDHead, int nIDLen, string sKeyField, string sAddinFilter, bool lIdIsNumber, OleDbCommand command)
{
string result = "";
OleDbConnection conn = null;
OleDbCommand cmd = command;
getDataCommand(cmd, ref conn, ref cmd);
bool lConn = conn.State == ConnectionState.Open;
OleDbDataReader dr = null;
//
UInt64 nMax = 0; //int n = nIDLen + sIDHead.Length;
string s = "", sMax = "0", sHead = (string.IsNullOrEmpty(sIDHead) ? "" : sIDHead.Trim()), sIDField = (string.IsNullOrEmpty(sKeyField) ? "sID" : sKeyField);
string sql = "select top 1 " + sIDField + " as sKey from " + sTable + " where 1=1 ";
if (!string.IsNullOrEmpty(sAddinFilter)) sql += " And (" + sAddinFilter + ") ";
/* 编号生成规则有3种:纯数字,前导0的数字,有编号头的。
* 纯数字:用dbo.isNumber函数检查
* 有编号头的:有头则like头,
* 没有编号头就是数字前导0,只判断首字母。
*/
if (lIdIsNumber)
{ //纯数字
sql += " and dbo.isNumber(" + sIDField + ")=1 ";
//排序
sql += " order by convert(numeric(20,4)," + sIDField + ") desc ";
}
else
{ //非纯数字的
if (!string.IsNullOrEmpty(sIDHead))
sql += " And " + sIDField + " like '" + sIDHead + "%' "; //有编号头的
else
sql += " And (subString(" + sIDField + ",1,1) between '0' and '9') "; //无编号头,但是前导0的
//编号长度
if (nIDLen > 0) sql += " and len(" + sIDField + ")=" + (nIDLen + sIDHead.Length).ToString();
//排序
sql += " Order By " + sIDField + " Desc "; //正序
}
//
try
{
if (!lConn) conn.Open();
//从数据库中取出最大的号
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
dr = cmd.ExecuteReader();
if (dr.Read() && dr["sKey"] != null) sMax = dr["sKey"].ToString();
if (string.IsNullOrEmpty(sMax)) sMax = "0";
//去掉头部 sMax = sMax.Substring(sHead.Length + 1, sMax.Length - sHead.Length - 1).Trim();
//周承昊:2010-9-13:当sMax="YG46002"时,取出来总是"6002"
if (sHead != "" && sMax.Length > sHead.Length) sMax = sMax.Remove(0, sHead.Length).Trim();
//换算成数字
try { nMax = Convert.ToUInt64(sMax); }
catch { }
//增加1
nMax++;
//返回值
if (lIdIsNumber) //纯数字
result = nMax.ToString();
else
result = sHead + nMax.ToString().PadLeft(nIDLen, '0');
}
catch (Exception x)
{ globalErrorString = "[buildNewID]生成新编号出错!" + x.Message; throw new Exception(globalErrorString); }
finally
{ if (!lConn) conn.Close(); if (dr != null) dr.Close(); }
//
return result;
}
#endregion

#region//设置字段外观,setFieldView。 DataColumn只能设置readonly和Caption,别的参数先留着备用
/// <summary>
/// 设置字段外观,DataColumn只能设置readonly和Caption,别的参数先留着备用
/// </summary>
/// <param name="data"></param>
/// <param name="sField"></param>
/// <param name="sCaption"></param>
/// <returns></returns>
//(Data:tDataSet;sField,sCaption:String;nWidth:Integer=-1;lVisible:Boolean=True;lReadOnly:Boolean=False):Boolean;
public static bool setFieldView(DataTable data, string sField, string sCaption)
{ return setFieldView(data, sField, sCaption, -1, true, false); }
public static bool setFieldView(DataTable data, string sField, string sCaption, string sFormat)
{ return setFieldView(data, sField, sCaption, sFormat, -1, true, false, -1); }
public static bool setFieldView(DataTable data, string sField, string sCaption, bool lVisible)
{ return setFieldView(data, sField, sCaption, -1, lVisible, false); }
public static bool setFieldView(DataTable data, string sField, string sCaption, int nWidth)
{ return setFieldView(data, sField, sCaption, nWidth, true, false); }
public static bool setFieldView(DataTable data, string sField, string sCaption, int nWidth, bool lVisible, bool lReadonly)
{ return setFieldView(data, sField, sCaption, "", nWidth, lVisible, lReadonly, -1); }
/// <summary>
/// 设置一个字段的外观显示,包括Caption、是否只读、是否可见等
/// </summary>
/// <param name="data">数据源</param>
/// <param name="sField">字段</param>
/// <param name="sCaption">标题</param>
/// <param name="nWidth">宽度,col.ExtendedProperties["Width"] = nWidth</param>
/// <param name="lVisible">可见否,col.ExtendedProperties["Visible"] = lVisible</param>
/// <param name="lReadonly">是否只读,此参数忽略</param>
/// <param name="nIndex">位置序号,为负数或超出有效范围则忽略</param>
/// <returns>返回成功与否</returns>
public static bool setFieldView(DataTable data, string sField, string sCaption, string sFormat, int nWidth, bool lVisible, bool lReadonly, int nIndex)
{ //设置一个字段的外观,留着参数以后用
bool result = false;
//
DataTable dt = data;
DataColumn col = null;
int i = 0;
//
try
{
col = dt.Columns[sField.Trim()];
if (col == null) return false; //查找字段,找不到就忽略
//设置
if (!string.IsNullOrEmpty(sCaption)) col.Caption = sCaption;
col.ExtendedProperties["Visible"] = lVisible;
col.ExtendedProperties["Width"] = nWidth;
col.ExtendedProperties["Format"] = sFormat;
//if (nWidth > 0) col.MaxLength = nWidth;
//col.ReadOnly = lReadonly;
//序号
if (nIndex >= 0 && nIndex <= data.Columns.Count - 1) col.SetOrdinal(nIndex);
//完成
result = true;
}
catch (Exception x)
{ }
//
return result;
}
public static bool setFieldViewHide(DataTable data, params string[] sFields)
{
bool result = false;
DataTable dt = data;
try
{
foreach (string sField in sFields)
{
DataColumn col = dt.Columns[sField.Trim()];
if (col == null) return false; //查找字段,找不到就忽略
//设置
col.ExtendedProperties["Visible"] = false;
}
result = true;
}
catch (Exception x)
{ }
return result;
}
#endregion

#region//向数据控件中写入值 setDbValue,对象可以是OleDbCommand的Param、DataRow的字段、DataTable的行
/// <summary>
/// 向数据控件中写入值 setDbValue
/// </summary>
/// <param name="dbObject">对象可以是OleDbCommand的Param、DataRow的字段、DataTable的行</param>
/// <param name="sParName">Param名、字段名</param>
/// <param name="oValue">要写入的值</param>
/// <returns>返回成功与否</returns>
public static bool setDbValue(object dbObject, string sParName, object oValue)
{ //设置数据控件的值
bool result = false;
object db = dbObject;
try
{
if (db is OleDbCommand)
{ //命令对象
(db as OleDbCommand).Parameters.AddWithValue(sParName, oValue);
result = true;
}
else if (db is DataRow)
{ //DataRow对象
DataRow row = db as DataRow;
if (row.Table.Columns.Contains(sParName)) row[sParName] = oValue;
result = true;
}
else if (db is DataTable)
{ //数据表,写第一行,没有则初始化一行
DataTable dt = db as DataTable;
DataRow row = null;
//如有则取第一行,否则增加一行并初始化之
if (dt.Rows.Count > 0) row = dt.Rows[0]; else { row = dt.NewRow(); Gs_DataFunction.initializeRecord(row); dt.Rows.Add(row); }
result = setDbValue(row, sParName, oValue); //递归
}
else
throw new Exception("不支持的类型!" + db.GetType().ToString());
}
catch (Exception x)
{ throw new Exception("[setDbValue]异常:\r\n" + x.Message); }
return result;
}
#endregion

#region//输出到excel,exportToExcel、gridToExcel,参考网站:http://hi.baidu.com/zagelover/blog/item/61eadacb17869dfb52664ff7.html
/// <summary>
/// 表格到Excel,来源自GridView,并下载
/// </summary>
/// <param name="page"></param>
/// <param name="grd"></param>
/// <param name="sFileName"></param>
/// <returns></returns>
public static bool exportToExcel(Page Page, Control objFrom, string sFileName)
{ //grid导出excel
bool result = false;
Control obj = objFrom;
HttpResponse Response = HttpContext.Current.Response; //Page.Response HttpContext.Current.Response
//
try
{
//清除Response缓存内容
Response.Clear();
//缓存输出,并在完成整个响应之后将其发送
Response.Buffer = true;
//设置输出流的HTPP字符集,确定字符的编码格式
Response.Charset = "GB2312"; //质疑
Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
//下面这行很重要, attachment 参数表示作为附件下载,您可以改成 online在线打开
Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(sFileName, System.Text.Encoding.UTF8)); //sFileName
//Response.ContentType指定文件类型.可以为application/ms-excel,application/ms-word,application/ms-txt,application/ms-html或其他浏览器可直接支持文档
Response.ContentType = "application/ms-excel";
//用GridView输出
Page.EnableViewState = false;
System.Globalization.CultureInfo myclt = new System.Globalization.CultureInfo("ZH-CN", true);
//
System.IO.StringWriter swBody = new System.IO.StringWriter(myclt);
System.Web.UI.HtmlTextWriter hwBody = new HtmlTextWriter(swBody);
//dv表示输出GridView,你也可以绑定datagrid,或其他支持obj.RenderControl()属性的控件
if (obj != null) obj.RenderControl(hwBody);// else Page.RenderControl(hwBody); //grd.RenderControl(hw);
Response.Write(swBody.ToString());
//消除乱码特别设定,非常规方法
/*string strExcel = "";
strExcel = "";
strExcel += hwBody.InnerWriter.ToString();
HttpContext.Current.Response.Write(strExcel); */
//完成
Response.End();
//
result = true;
}
catch (Exception x)
{
result = true;
//throw new Exception("[gridToExcel]输出excel出错!"+x.Message);
}
//
return result;
}
/*覆盖系统的验证,输出xls时会出一个“需要runat=server”,此函数覆盖之
public override void VerifyRenderingInServerForm(Control control)
{
// Confirms that an HtmlForm control is rendered for
//导出列表到Excel,如果不过载这个虚函数,就会在试图将GRIDVIEW中的数据导出至EXCEL时抛出异常:
//类型“GridView”的控件“ctl00_content_gridView1”必须放在具有 runat=server 的窗体标记内。
//页面是从母版页继承的,而gridview所在的ContentPlaceHolder确定是放在form中的。以前只有控件未放在form中才会抛出同类异常。
} */
public static bool exportToExcel(string strFileName, DataTable data)
{ //用dataTable输出excel
bool result = false, lVisible = true;
object o = "", oValue = "";
string s = "", sFmt = "";
ArrayList cols = new ArrayList();
DataColumn col = null;
//
HttpResponse Response = HttpContext.Current.Response; //Page.Response HttpContext.Current.Response
//
try
{
//清除Response缓存内容
Response.Clear();
//缓存输出,并在完成整个响应之后将其发送
Response.Buffer = true;
//strFileName指定输出文件的名称,注意其扩展名和指定文件类型相符,可以为:.doc .xls .txt .htm
if (new System.IO.FileInfo(strFileName).Extension.ToLower() != ".xls") strFileName += ".xls"; //xls csv
//设置输出流的HTPP字符集,确定字符的编码格式
//HttpContext.Current.Response.Charset = "UTF-8";
Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
//下面这行很重要, attachment 参数表示作为附件下载,您可以改成 online在线打开
Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(strFileName));
//Response.ContentType指定文件类型.可以为application/ms-excel,application/ms-word,application/ms-txt,application/ms-html或其他浏览器可直接支持文档
Response.ContentType = "application/ms-excel";

string colHeaders = "", ls_item = "";
int i = 0;
//定义表对象与行对像,同时用DataSet对其值进行初始化
DataRow[] myRow = data.Select("");
//取可用的字段列表
cols.Clear();
for (i = 0; i < data.Columns.Count; i++)
{
col = data.Columns[i];
lVisible = getColumnVisibleProperty(col);
if (lVisible) cols.Add(col.ColumnName); //不可见,则忽略之
}
//取得数据表各列标题,各标题之间以\t分割,最后一个列标题后加回车符
for (i = 0; i < cols.Count - 1; i++) colHeaders += data.Columns[cols[i].ToString()].Caption.ToString() + "\t";
colHeaders += data.Columns[cols[i].ToString()].Caption.ToString() + "\n"; //最后一行,换行符
Response.Write(colHeaders); //向HTTP输出流中写入取得的数据信息
//逐行处理数据
foreach (DataRow row in myRow)
{
//在当前行中,逐列获得数据,数据之间以\t分割,结束时加回车符\n。
for (i = 0; i < (cols.Count - 1); i++)
{
string sColName = cols[i].ToString(); //列英文名
col = data.Columns[sColName]; //引用此列
sFmt = getColumnFormatProperty(col).Trim(); //格式化字符串
//取值
o = row[sColName];
oValue = o;
if (!string.IsNullOrEmpty(sFmt)) oValue = string.Format(sFmt, oValue);
//文本之前加单引号区分开。
if (col.DataType == typeof(string))
{
s = oValue == null ? "" : oValue.ToString();
if (s.Length > 8 && s[0] >= '0' && s[0] <= '9') oValue = "'" + s;
}
//逻辑值
if (oValue is Boolean) oValue = (Convert.ToBoolean(oValue) ? "是" : "否");
//移除\r\n
s = exportExcelAddSplitChar(oValue.ToString());
ls_item += s + "\t";
}
//最后一列
sFmt = getColumnFormatProperty(data.Columns[cols[i].ToString()]).Trim(); //取出格式化字符串
oValue = row[cols[i].ToString()];
if (!string.IsNullOrEmpty(sFmt)) oValue = string.Format(sFmt, oValue); //转化成格式
s = exportExcelAddSplitChar(oValue.ToString());
//最后一列,要加回车符
ls_item += s + "\n";
/* for (i = 0; i < data.Columns.Count - 1; i++) ls_item += row[i].ToString() + "\t";
ls_item += row[i].ToString() + "\n"; */
//当前行数据写入HTTP输出流,并且置空ls_item以便返程数据
Response.Write(ls_item);
ls_item = "";
}
//写缓冲区中的数据到HTTP头文件中
Response.End();
//
result = true;
}
catch
{ }
//
return result;
}
private static string exportExcelAddSplitChar(string s)
{ //输出excel时,如果中间包含回车换行,则需要用双引号套起来
string result = s, sEnter = "\r\n"; //Convert.ToChar(13).ToString() + Convert.ToChar(10).ToString();
if (result.Contains("\r") || result.Contains("\n")) result = "\"" + result + "\"";
return result;
}
public static bool exportToExcel(Page Page, OleDbDataReader dataReader, string sFileName)
{ //输出到Excel,从DataReader中
return true;
}
public static bool getColumnVisibleProperty(DataColumn col)
{ //获取Column的Visible扩展属性
bool result = true;
if (col.ExtendedProperties.ContainsKey("Visible"))
try
{ result = Convert.ToBoolean(col.ExtendedProperties["Visible"]); }
catch { }
//
return result;
}
public static string getColumnFormatProperty(DataColumn col)
{ //获取col的格式设置
string result = "";
if (col.ExtendedProperties.ContainsKey("Format"))
try { result = Convert.ToString(col.ExtendedProperties["Format"]); }
catch { }
//完成
return result;
}
public static int getColumnWidthProperty(DataColumn col)
{ //获取col的宽度
int result = -1;
if (col.ExtendedProperties.ContainsKey("Width"))
try { result = Convert.ToInt16(col.ExtendedProperties["Width"]); }
catch { }
//完成
return result;
}
#endregion

#region//从dataReader中查找字段的序号,没有返回-1,getFieldIndex。
/// <summary>
/// //从dataReader中查找字段的序号,没有返回-1
/// </summary>
public static int getFieldIndex(OleDbDataReader db, string sField)
{ //从dataReader中查找字段的序号,没有返回-1
int result = -1, i = 0;
string s = "";
for (i = 0; i < db.FieldCount; i++) if (db.GetName(i).Trim().ToUpper() == sField.Trim().ToUpper()) return i;
return result;
}
public static int getFieldIndex(DataTable db, string sField)
{ //从dataReader中查找字段的序号,没有返回-1
int result = -1, i = 0;
string s = sField.ToUpper().Trim();
for (i = 0; i < db.Columns.Count; i++) if (db.Columns[i].ColumnName.Trim().ToUpper() == s) return i;
return result;
}
#endregion

#region //设置字段的位置
/// <summary>
/// 设置字段的位置
/// </summary>
/// <param name="db">数据源</param>
/// <param name="sField">字段</param>
/// <param name="nIndex">位置</param>
/// <returns>非法返回-1;否则返回列位置</returns>
public static int setFieldIndex(DataTable db, string sField, int nIndex)
{ //设置字段列的位置
int result = -1;
if (getFieldIndex(db, sField) > -1 && db.Columns.Count>nIndex ) { db.Columns[sField].SetOrdinal(nIndex); result = nIndex; }
return result;
}
public static int setFieldIndexAfter(DataTable db, string sField, string sAfterThisField)
{
int result = -1;
int /*n1 = getFieldIndex(db, sField),*/ n2 = getFieldIndex(db, sAfterThisField);
if (/*n1 < 0 ||*/ n2 < 0) return result; //字段无效
result = setFieldIndex(db, sField, n2 + 1); //移动
return result;
}
public static int moveFieldAfter(DataTable db, string sField, string sAfterThisField)
{
return setFieldIndexAfter(db, sField, sAfterThisField);
}
#endregion

#region //填充数据到下拉列表 fillComboBox fillComboBoxWithBlank
/// <summary>
/// 填充数据到下拉列表
/// </summary>
public static bool fillComboBox(DropDownList cbx, string sTableName)
{
return fillComboBox(null as OleDbConnection, cbx, "select * from " + sTableName, "", "");
}
public static bool fillComboBox(OleDbConnection connection, DropDownList cbx, string sScript, string sValueField, string sCaptionField)
{ //填充dropDown,用connection读取数据
OleDbCommand cmd = new OleDbCommand(sScript, connection);
return fillComboBox(cmd, cbx, sScript, sValueField, sCaptionField);
}
/// <summary>
/// 填充数据到下拉列表DropdownList,用command做数据访问。填充前不清空dropdownList的原有项目。
/// </summary>
/// <param name="command">用此command访问数据库,类似delphi的TAdoQuery</param>
/// <param name="cbx">填充到此控件中,填充前不清空原有项目</param>
/// <param name="sScript">用此脚本读取数据</param>
/// <param name="sValueField">填充项的Value字段,默认为sID</param>
/// <param name="sCaptionField">填充项的Text字段,默认为sName</param>
/// <returns>返回成功与否</returns>
public static bool fillComboBox(OleDbCommand command, DropDownList cbx, string sScript, string sValueField, string sCaptionField)
{ //填充dropDown,用Command读取数据
bool result = false;
string slCapField = sCaptionField.Trim(), slIDField = sValueField.Trim(), sConn = "";
if (slCapField == "") slCapField = "sName";
if (slIDField == "") slIDField = "sID";
//
OleDbConnection conn = null;
OleDbCommand cmd = command;
getDataCommand(cmd, ref conn, ref cmd);
OleDbDataReader dr = null;
bool lConn = conn.State == ConnectionState.Open;
//
try
{
if (!lConn) conn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = sScript;
//读取,并循环加入
dr = cmd.ExecuteReader();
while (dr.Read())
cbx.Items.Add(new ListItem(dr[slCapField].ToString(), dr[slIDField].ToString()));
//完成
result = true;
}
catch (Exception x)
{ throw new Exception("[fillComboBox]填充内容错误!" + x.Message); }
finally
{ if (dr != null) dr.Close(); if (!lConn) conn.Close(); } //必须显式关闭DataReader,如果传来的连接不是打开的或没有传来,则关闭之
//完成,返回
return result;
}
/// <summary>
/// 填充数据到下拉列表,填充前加一个空“”值的项目。
/// </summary>
public static bool fillComboBoxWithBlank(OleDbConnection connection, DropDownList cbx, string sScript, string sValueField, string sCaptionField)
{ //带空行
if (cbx.Items.FindByValue("") == null) cbx.Items.Add(new ListItem("", ""));
return Gs_DataFunction.fillComboBox(connection, cbx, sScript, sValueField, sCaptionField);
}
public static bool fillComboBoxWithBlank(OleDbCommand command, DropDownList cbx, string sScript, string sValueField, string sCaptionField)
{ //带空行添加
if (cbx.Items.FindByValue("") == null) cbx.Items.Add(new ListItem("", ""));
return Gs_DataFunction.fillComboBox(command, cbx, sScript, sValueField, sCaptionField);
}
/// <summary>
/// 填充Combobox的递归执行
/// </summary>
public static bool fillComboBoxRecursive(OleDbCommand command, DropDownList cbx, string sTable, string sParent, string sAddinFilter, int nLevel)
{ return fillComboBoxRecursive(command, cbx, sTable, sParent, sAddinFilter, "", nLevel); }
/// <summary>
/// 填充Combobox的递归执行
/// </summary>
/// <param name="command">ole数据组件</param>
/// <param name="cbx">下拉框</param>
/// <param name="sTable">表名,数据来源</param>
/// <param name="sParent">上记号sParent字段</param>
/// <param name="sWhere">SQL的Where条件</param>
/// <param name="sOrderBy">SQL的OrderBy字段</param>
/// <param name="nLevel">级别,备用的,意义不大</param>
/// <returns>返回成功与否</returns>
public static bool fillComboBoxRecursive(OleDbCommand command, DropDownList cbx, string sTable, string sParent, string sWhere, string sOrderBy, int nLevel)
{ //填充的执行过程
bool lResult = false, lConn = true;
if (cbx == null) return false;
string s = "", sID = "", sName = "", sF = "", sql = "select sID, sName, sParent from " + sTable + " as Sections where lEnable=1 ";
sql += " and sParent='" + sParent + "' ";
if (!string.IsNullOrEmpty(sWhere)) sql += " And (" + sWhere + ") ";
if (!string.IsNullOrEmpty(sOrderBy)) sql += " order by (" + sOrderBy + ") ";
for (int i = 0; i < nLevel; i++) s += " "; //nLevel-1
//if (s != "") s += "┗";
//
OleDbCommand cmd = command;
DataTable dt = null;
try
{
Gs_DataFunction.getSqlResult(sql, ref dt, cmd);
//
foreach (DataRow db in dt.Rows)
{
sID = db["sID"].ToString();
sName = s + db["sName"].ToString();
cbx.Items.Add(new ListItem(sName, sID));
//递归调用
fillComboBoxRecursive(cmd, cbx, sTable, sID, sWhere, nLevel + 1);
}
//完毕
lResult = true;
}
catch (Exception x)
{ Gs_DataFunction.globalErrorString = x.Message; throw new Exception("[fillComboBoxRecursive]递归填充出错!" + x.Message); }
finally
{
if (command == null && cmd != null) cmd.Dispose(); //释放资源
if (dt != null) dt.Dispose();
}
//
return lResult;
}
#endregion

#region //填充DataGrid表格,FillDataGrid。默认通过DataAdapter填充DataSet,然后用DataSet填充表格
/// <summary>
/// 填充DataGrid表格,FillDataGrid。默认通过DataAdapter填充DataSet,然后用DataSet填充表格
/// </summary>
public static bool FillDataGrid(OleDbConnection connection, DataGrid grd, string sScript)
{
string sConn = "";
DataSet dt = new DataSet();
OleDbConnection conn = connection;
if (conn == null)
conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]); //_Default.sConnectionString
OleDbDataAdapter da = new OleDbDataAdapter(sScript, conn); //脚本
try
{
da.Fill(dt, "TableByFillDataGrid");
grd.DataSource = dt;
grd.DataBind();
//
return true;
}
catch (Exception x)
{
throw new Exception("[FillDataGrid]填充数据表出错!\n " + x.Message + "\n " + sScript);
return false;
}
finally
{
if (connection == null) conn.Close();
}
}
#endregion

#region //getDataCommand:获取可用的command和connection,getDataCommand。在许多处理中,传入oledbCommand作为参数,参数可以为null,自动处理
/// <summary>
/// 获取可用的command和connection。在许多处理中,传入oledbCommand作为参数,参数可以为null,自动处理
/// </summary>
/// <param name="commandFromParam">作为参数传入的Command</param>
/// <param name="connection">返回一个可用的command实例</param>
/// <param name="command">返回一个可用的connection实例</param>
/// <returns>成功与否</returns>
public static bool getDataCommand(OleDbCommand commandFromParam, ref OleDbConnection connection, ref OleDbCommand command)
{
command = commandFromParam;
if (command == null)
{
connection = getNewConnection();
command = new OleDbCommand("", connection);
}
else
{
connection = command.Connection;
}
if (connection == null) connection = getNewConnection();
if (command == null) command = new OleDbCommand("", connection); //20130606周承昊加入
if (command.Connection == null) command.Connection = connection;
//
return true;
}
/// <summary>
/// 获取可用的command和connection、Transaction事务。在许多处理中,传入oledbCommand作为参数,参数可以为null,自动处理
/// </summary>
/// <param name="commandFromParam">作为参数传入的Command</param>
/// <param name="connection">返回一个可用的command实例</param>
/// <param name="command">返回一个可用的connection实例</param>
/// <param name="transaction">返回一个可用的transaction事务实例</param>
/// <returns>成功与否</returns>
public static bool getDataCommand(OleDbCommand commandFromParam, ref OleDbConnection connection, ref OleDbCommand command, ref OleDbTransaction transaction)
{
bool result = false;
try
{
if (!getDataCommand(commandFromParam, ref connection, ref command)) return false;
//事务
transaction = command.Transaction;
if (transaction == null)
{ //事务启动,前提是打开连接
if (connection.State != ConnectionState.Open) connection.Open();
transaction = connection.BeginTransaction();
command.Transaction = transaction;
}
//完成
result = true;
}
catch (Exception x)
{ throw new Exception("[getDataCommand-Transaction]获取可用的事务、命令、连接出错!\r\n" + x.Message); }
//返回
return result;
}
#endregion

#region //getDataAdapter:生成可以OleDbDataAdapter.Update(DataSet)更新的DataSet和OleDbDataAdapter
/// <summary>
/// 生成可用于update的adapter,修改data的数据后,调用adapter.update(data)即可更新数据,等效于delphi的dataSet。
/// 辅助处理有: Gs_DataFunction.initializeRecord初始化数据,Gs_Class.getDefaultValueOfType
/// </summary>
/// <param name="commandPar">用来取参数包括connection和transaction的命令,执行后其commandText会变成读取数据的脚本</param>
/// <param name="sSelectScript">读取数据的脚本</param>
/// <param name="da">返回的OleDbDataAdapter数据适配器,传入null用commandPar生成,否则将其SelectCommand设置成commandPar</param>
/// <param name="data">返回数据集,处理完后,可以用OleDbDataAdapter.Update(DataSet)更新数据</param>
/// <returns>成功与否</returns>
public static bool getDataAdapter(OleDbCommand commandPar, string sSelectScript, ref OleDbDataAdapter da, ref DataSet data)
{
bool result = false;
OleDbCommand cmd = null;
OleDbConnection conn = null;
OleDbCommandBuilder builder = null;
Gs_DataFunction.getDataCommand(commandPar, ref conn, ref cmd); //确保实例化
bool lConn = conn.State == ConnectionState.Open;
try
{
cmd.CommandText = sSelectScript;
if (da == null)
da = new OleDbDataAdapter(cmd); //没有则生成一个
else
da.SelectCommand = cmd; //用这个comman
if (data == null) data = new DataSet("queryResult");
//生成相应脚本,此步忽略
builder = new OleDbCommandBuilder(da);
if (conn.State != ConnectionState.Open) conn.Open();
if (da.InsertCommand == null) da.InsertCommand = builder.GetInsertCommand();
if (da.DeleteCommand == null) da.DeleteCommand = builder.GetDeleteCommand();
if (da.UpdateCommand == null) da.UpdateCommand = builder.GetUpdateCommand();
//设置关键属性,command的事务需要是统一的,要不不受transaction控制
da.InsertCommand.Transaction = cmd.Transaction;
da.DeleteCommand.Transaction = cmd.Transaction;
da.UpdateCommand.Transaction = cmd.Transaction;
//读取数据
da.Fill(data);
//完成
result = true;
}
catch (Exception x)
{ //捕获错误
if (!lConn) conn.Close();
Gs_DataFunction.globalErrorString = "[getDataAdapter]生成数据和数据适配器出错!\r\n" + x.Message;
throw new Exception(Gs_DataFunction.globalErrorString);
}
return result; //完成
}
/// <summary>
/// 生成可用于update的adapter,修改data的数据后,调用adapter.update(data)即可更新数据,等效于delphi的dataSet。
/// 辅助处理有: Gs_DataFunction.initializeRecord初始化数据,Gs_Class.getDefaultValueOfType
/// </summary>
/// <param name="commandPar">用来取参数包括connection和transaction的命令,执行后其commandText会变成读取数据的脚本</param>
/// <param name="sSelectScript">读取数据的脚本</param>
/// <param name="da">返回的OleDbDataAdapter数据适配器,传入null用commandPar生成,否则将其SelectCommand设置成commandPar</param>
/// <param name="data">返回DataTable,处理完后,可以用OleDbDataAdapter.Update(DataTable)</param>
/// <returns>成功与否</returns>
public static bool getDataAdapter(OleDbCommand commandPar, string sSelectScript, ref OleDbDataAdapter da, ref DataTable data)
{ //用table返回
DataSet ds = null;
bool result = getDataAdapter(commandPar, sSelectScript, ref da, ref ds);
if (result) data = ds.Tables[0];
return result;
}
/// <summary>
/// 生成可用于update的adapter,修改data的数据后,调用adapter.update(data)即可更新数据,等效于delphi的dataSet。
/// 辅助处理有: Gs_DataFunction.initializeRecord初始化数据,Gs_Class.getDefaultValueOfType
/// </summary>
/// <param name="commandPar">用来取参数包括connection和transaction的命令,执行后其commandText会变成读取数据的脚本</param>
/// <param name="sSelectScript">读取数据的脚本</param>
/// <param name="da">返回的OleDbDataAdapter数据适配器,传入null用commandPar生成,否则将其SelectCommand设置成commandPar</param>
/// <param name="data">返回DataRow,有记录则直接取,无则添加后初始化</param>
/// <returns>成功与否,处理完后,可以用OleDbDataAdapter.Update(DataRow)</returns>
public static bool getDataAdapter(OleDbCommand commandPar, string sSelectScript, ref OleDbDataAdapter da, ref DataTable dt, ref DataRow data)
{
bool result = getDataAdapter(commandPar, sSelectScript, ref da, ref dt);
if (!result) throw new Exception("生成出错!");
//有则直接取,无则添加后初始化
if (dt.Rows.Count > 0) data = dt.Rows[0]; else { data = dt.NewRow(); initializeRecord(data); dt.Rows.Add(data); }
return true;
}
#endregion

#region //设置字段的默认值,setFieldsDefaultValue
/// <summary>
/// 设置字段的默认值
/// </summary>
/// <param name="db">要设置的数据表</param>
/// <returns>成功与否</returns>
public static bool setFieldsDefaultValue(DataTable db)
{
bool result = false;
DataTable dt = db;
DataColumn col = null;
object oValue = null;
int i = 0;
for (i = 0; i < dt.Columns.Count; i++)
{ //遍历所有列
col = dt.Columns[i];
if (col.DefaultValue != null || col.AutoIncrement || col.ReadOnly) continue; //不用设置:已经有了、自动增长、只读
col.DefaultValue = Gs_Class.getDefaultValueOfType(col.DataType);
}
//
return true;
}
#endregion

#region //initializeRecord:初始化数据
/// <summary>
/// 初始化数据,此处为设置DataTable里DataColumn.DefaultValue
/// </summary>
/// <param name="db">要设置的数据表</param>
/// <returns>返回成功与否</returns>
public static bool initializeRecord(DataTable db)
{ //设置默认值
return setFieldsDefaultValue(db);
}
/// <summary>
/// 初始化数据,此处为设置DataRow的值
/// </summary>
/// <param name="db">数据DataRow</param>
/// <returns>成功与否</returns>
public static bool initializeRecord(DataRow db)
{ //设置默认值
bool result = false;
DataTable dt = db.Table;
DataColumn col = null;
object oValue = null;
int i = 0;
for (i = 0; i < dt.Columns.Count; i++)
{ //遍历所有列
col = dt.Columns[i];
if (col.AutoIncrement || col.ReadOnly) continue; //不用设置:已经有了、自动增长、只读
db[i] = Gs_Class.getDefaultValueOfType(col.DataType);
}
//
return true;
}
#endregion

#region//执行SQL脚本,DoSQL,无返回,无事务 DoSQL(OleDbConnection connection, string sScriptNonReturn)
/// <summary>
/// 执行SQL脚本。注意:可以用lock锁定线程防止多人操作。 #if checked unchecked fixed lock System.Diagnostics.Process.Start("ipconfig /all");
/// </summary>
public static int DoSQL(OleDbConnection connection, string sScriptNonReturn)
{
int result = -1;
//
OleDbConnection conn = connection;
if (conn == null)
conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]); //_Default.sConnectionString
OleDbCommand cmd = new OleDbCommand(sScriptNonReturn, conn);
ConnectionState cs = conn.State; //状态
try
{
if (conn.State == ConnectionState.Closed) conn.Open();
result = cmd.ExecuteNonQuery();
}
catch (Exception x)
{
globalErrorString = "[DoSQL]执行SQL脚本出错!\n " + x.Message + "\n " + sScriptNonReturn;
throw new Exception(globalErrorString);
}
finally
{ if (connection == null) conn.Close(); }
//
return result;
}
#endregion

#region//执行SQL脚本,DoSQL,传来统一事务 DoSQL(string sScript, OleDbTransaction trans)
public static int DoSQL(string sScript, OleDbTransaction trans)
{
int result = -1;
OleDbConnection conn = null;
OleDbCommand cmd = null;
if (trans == null) conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]); else conn = trans.Connection;
cmd = new OleDbCommand(sScript, conn);
if (trans != null) cmd.Transaction = trans;
//
try
{
if (trans == null) conn.Open(); //无传入,自己打开
cmd.CommandText = sScript;
result = cmd.ExecuteNonQuery();
}
finally
{
if (trans == null) conn.Close(); //无传入,自己关闭
}
//
return result;
}
#endregion

#region//执行SQL脚本,DoSQL,返回受影响的行数。command传送来后可以启动外部统一事务 DoSQL(string sScript, OleDbCommand command)
/// <summary>
/// 执行SQL脚本,返回受影响的行数。command可以带事务,也可以通过lTransaction参数请求启动事务。
/// </summary>
public static int DoSQL(string sScript, OleDbCommand command)
{
return DoSQL(sScript, command, false);
}
/// <summary>
/// 执行SQL脚本,DoSQL,返回受影响的行数。command可以带事务,也可以通过lTransaction参数请求启动事务
/// </summary>
/// <param name="sScript">要执行的脚本,无返回值,执行后返回受此脚本影响的行数</param>
/// <param name="command">通过此command执行,如果是null则内部创建</param>
/// <param name="lTransaction">是否启动事务,如果command带事务,则忽略此参数</param>
/// <returns>返回受脚本影响的行数</returns>
public static int DoSQL(string sScript, OleDbCommand command, bool lTransaction)
{
if (sScript == "") return 0;
int result = -1;
//容错处理,若无参数,则创建
OleDbCommand cmd = command;
OleDbConnection conn = null;
getDataCommand(cmd, ref conn, ref cmd);
OleDbTransaction trans = cmd.Transaction;
//保存原状态
bool lConn = conn.State == ConnectionState.Open, lTrans = trans != null;
CommandType ct = cmd.CommandType;
//
try
{
if (!lConn) conn.Open();
//事务,当要求自动启动事务,且事务没有启动时
if (lTransaction && !lTrans) { trans = conn.BeginTransaction(); cmd.Transaction = trans; }
//
cmd.CommandType = CommandType.Text;
cmd.CommandText = sScript;
result = cmd.ExecuteNonQuery();
//完成,事务
if (lTransaction && !lTrans) trans.Commit(); //要求事务,且内部启动的事务
}
catch (Exception x)
{
if (lTrans && !lTrans && trans != null) trans.Rollback(); //要求事务,且是内部启动了事务
globalErrorString = "[DoSQL]执行脚本出错!" + (char)13 + x.Message + (char)13 + sScript;
throw new Exception(globalErrorString);
}
finally
{ //复原其状态
if (!lConn) conn.Close();
if ((command != null) && (cmd.CommandType != ct)) cmd.CommandType = ct;
}
return result;
}
#endregion

#region//获取SQl返回值,getSqlResult,获取返回的一个字段值,可以取默认值
/// <summary>
/// 获取SQl返回值,sql脚本必须包含select @XXX as nResult结尾,内部用DataReader读取第一个数字字段。
/// 注意:可以用lock锁定线程防止多人操作。 #if checked unchecked fixed lock System.Diagnostics.Process.Start("ipconfig /all");
/// </summary>
/// <param name="sql">sql脚本必须包含select @XXX as nResult结尾,内部用DataReader读取第一个数字字段</param>
/// <param name="lTransaction">是否启动事务</param>
/// <returns></returns>
public static object getSqlResult(string sql, OleDbCommand command, bool lTransaction)
{ return Gs_DataFunction.getSqlResult(sql, null, command, lTransaction); }
public static object getSqlResult(string sScript, object defaultValue, OleDbConnection connection)
{ return getSqlResult(sScript, defaultValue, connection, false); }
public static object getSqlResult(string sScript, object defaultValue, OleDbConnection connection, bool lTransaction)
{ //取返回值
OleDbConnection conn = connection;
if (conn == null) conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]);
OleDbCommand cmd = new OleDbCommand("", conn);
//
return getSqlResult(sScript, defaultValue, cmd, lTransaction);
}
//////////
public static object getSqlResult(string sScript, object defaultValue, OleDbCommand command)
{ return getSqlResult(sScript, defaultValue, "", command); }
public static object getSqlResult(string sScript, object defaultValue, string sField, OleDbCommand command)
{ return getSqlResult(sScript, defaultValue, sField, command, false); }
/// <summary>
/// 获取SQl返回值,getSqlResult,获取返回的一个字段值,可以取默认值。sql脚本必须包含select @XXX as YYY结尾,内部用DataReader读取第一个数字字段
/// </summary>
/// <param name="sScript">要执行的脚本,必须包含select @XXX as YYY结尾,内部用DataReader读取第一个数字字段</param>
/// <param name="defaultValue">默认值</param>
/// <param name="sField">要取的字段名</param>
/// <param name="command">使用的command执行,如果是null则内部创建</param>
/// <param name="lTransaction">是否启动事务,如果command带了事务则忽略此参数</param>
/// <returns>返回脚本读取的值</returns>
public static object getSqlResult(string sScript, object defaultValue, string sField, OleDbCommand command, bool lTransaction)
{ //取返回值
object result = defaultValue;
//
OleDbCommand cmd = command;
OleDbConnection conn = null;
getDataCommand(cmd, ref conn, ref cmd);
DataTable dt = null;
DataRow row = null;
bool lConn = conn.State == ConnectionState.Open;
//
try
{
if (!lConn) conn.Open();
//执行读取
if (getSqlResult(sScript, ref dt, cmd, lTransaction) && dt.Rows.Count > 0) row = dt.Rows[0]; //读取出来
if (row != null) { if (string.IsNullOrEmpty(sField)) result = row[0]; else result = row[sField]; }
//完成
if (result == null) result = defaultValue;
}
catch (Exception x)
{ throw new Exception("[getSqlResult-Object]获取SQL返回值出错!\r\n" + x.Message+" \r\n"+sScript); }
finally
{ if (!lConn) conn.Close(); dt = null; }
//返回值
return result;
}
public static object getSqlResult(string sScript, object defaultValue, OleDbCommand command, bool lTransaction)
{ return getSqlResult(sScript, defaultValue, "", command, false); }
public static double getSqlResultFloat(string sScript, double defaultValue, OleDbCommand command)
{ return gsClass.varToFloatDef(getSqlResult(sScript, defaultValue, command), defaultValue); }
#endregion

#region//获取SQl返回值,getSqlResult,返回DataTable,可以通过command带事务或通过lTransaction参数请求启动事务
/// <summary>
/// 获取SQl返回值,返回DataTable,可以通过command带事务或通过lTransaction参数请求启动事务。
/// </summary>
public static bool getSqlResult(string sScript, ref DataTable table, OleDbCommand command)
{ return getSqlResult(sScript, ref table, command, false); }
/// <summary>
/// 获取SQl返回值,返回值放入dataTable,可以内部启动事务
/// </summary>
/// <param name="sScript">要执行的脚本,包含返回table</param>
/// <param name="table">返回值存入此table</param>
/// <param name="command">用此命令控件执行,如果是null则内部创建。</param>
/// <param name="lTransaction">是否启动事务,如果command带事务则忽略参数</param>
/// <returns>成功与否</returns>
public static bool getSqlResult(string sScript, ref DataTable table, OleDbCommand command, bool lTransaction)
{ //返回记录集
bool result = false, vR = false;
if (table == null) table = new DataTable();
//
OleDbCommand cmd = command;
OleDbConnection conn = null;
getDataCommand(cmd, ref conn, ref cmd);
OleDbTransaction trans = cmd.Transaction;
OleDbDataReader dr = null;
bool lConn = conn.State == ConnectionState.Open, lTrans = trans != null;
//
try
{
if (!lConn) conn.Open();
if (lTransaction && !lTrans) { trans = conn.BeginTransaction(); cmd.Transaction = trans; } //启动事务
//读取数据
if (!getSqlResult(sScript, ref dr, cmd)) throw new Exception("读取数据出错!");
//把数据读入到DataTable中:读取字段列表
vR = dataReader2DataTable(dr, ref table);
//完成
if (lTransaction && !lTrans) trans.Commit(); //要求启动事务,且内部事务
result = vR;
}
catch (Exception x)
{
if (lTransaction && !lTrans && trans != null) trans.Rollback(); //内部事务,撤消之
throw new Exception("[getSqlResult-DataTable]获取DataTable出错!\r\n" + x.Message);
}
finally
{ if (!lConn) conn.Close(); if (dr != null)dr.Close(); }
return result;
}
/// <summary>
/// 获取SQl返回值,返回DataRow,可以通过command带事务或通过lTransaction参数请求启动事务。
/// </summary>
/// <param name="sScript"></param>
/// <param name="db"></param>
/// <param name="command"></param>
/// <returns></returns>
public static bool getSqlResult(string sScript, ref DataRow db, OleDbCommand command)
{ return getSqlResult(sScript, ref db, command, false); }
/// <summary>
/// 获取SQl返回值,返回值放入DataRow,可以内部启动事务
/// </summary>
/// <param name="sScript">要执行的脚本,包含返回table</param>
/// <param name="table">返回值存入此DataRow</param>
/// <param name="command">用此命令控件执行,如果是null则内部创建。</param>
/// <param name="lTransaction">是否启动事务,如果command带事务则忽略参数</param>
/// <returns>成功与否</returns>
public static bool getSqlResult(string sScript, ref DataRow db, OleDbCommand command, bool lTransaction)
{
DataTable dt = null;
bool result = getSqlResult(sScript, ref dt, command, lTransaction);
if (result && dt != null && dt.Rows.Count > 0)
{
db = dt.Rows[0];
result = true;
}
return result; //完成
}
#endregion

#region//获取SQl返回值,getSqlResult,返回DataReader。警告:为了让DataReader可以在函数外边继续Read,将不会关闭Connection。
/// <summary>
/// 获取SQl返回值,返回DataTable。警告:为了让DataReader可以在函数外边继续Read,将不会关闭Connection
/// </summary>
public static bool getSqlResult(string sScript, ref OleDbDataReader dr, OleDbConnection connection)
{ //返回记录集
OleDbConnection conn = connection;
if (conn == null) conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]);
OleDbCommand cmd = new OleDbCommand(sScript, conn);
return getSqlResult(sScript, ref dr, cmd);
}
/// <summary>
/// 获取SQl返回值,返回DataTable。
/// 警告:为了让DataReader可以在函数外边继续Read,将不会关闭Connection。
/// 可通过command本身带事务,command的事务提交或撤消后,其DataReader读取数据会出错!!!!!所以此模块不支持lTransaction事务请求
/// </summary>
/// <param name="sScript">脚本,可用dataReader读取</param>
/// <param name="dr">返回dataReader</param>
/// <param name="command">使用此command执行,如果是null则内部创建</param>
/// <returns>成功与否</returns>
public static bool getSqlResult(string sScript, ref OleDbDataReader dr, OleDbCommand command)
{ //返回记录集
if (sScript == "") return false;
bool result = false, lTransaction = false;
//容错处理,若无参数,则创建
OleDbCommand cmd = command;
OleDbConnection conn = null;
getDataCommand(cmd, ref conn, ref cmd);
OleDbTransaction trans = cmd.Transaction;
//保存原状态
bool lConn = conn.State == ConnectionState.Open, lTrans = trans != null;
CommandType ct = cmd.CommandType;
//
try
{
if (!lConn) conn.Open();
if (lTransaction && !lTrans) { trans = conn.BeginTransaction(); cmd.Transaction = trans; }
//执行
cmd.CommandType = CommandType.Text;
cmd.CommandText = sScript;
dr = cmd.ExecuteReader();
//完成返回
if (lTransaction && !lTrans)
{
trans.Commit(); //要求启动事务,且事务是从内部启动的,则提交
cmd.Transaction = null;
}
result = true;
}
catch (Exception x)
{
if (lTransaction && !lTrans && trans != null) trans.Rollback(); //内部启动的事务,撤消
globalErrorString = "[getSqlResult-DataReader]获取SQl返回值出错!\r\n" + x.Message;
throw new Exception(globalErrorString);
}
finally
{ //复原其状态
if ((command != null) && (cmd.CommandType != ct)) cmd.CommandType = ct;
//if (!lConn) conn.Close(); //关闭之后,DataReader将无法读取,不知DataReader是不是会被释放?
}
//完成,返回
return result;
}
#endregion

#region//获取SQl返回值:数据集,getSqlResultDataSet,返回DataSet或DataReader
/// <summary>
/// 获取SQl返回值:数据集,返回OleDbDataReader。注意:可以用lock锁定线程防止多人操作。 #if checked unchecked fixed lock System.Diagnostics.Process.Start("ipconfig /all");
/// </summary>
public static OleDbDataReader getSqlResultDataReader(OleDbCommand command, string sqlScript)
{
OleDbDataReader result = null;
if (!getSqlResult(sqlScript, ref result, command))
throw new Exception("[getSqlResultDataSet-DataReader]获取SQl返回值出错!" + globalErrorString);
return result;
}
public static DataSet getSqlResultDataSet(OleDbCommand command, string sqlScript)
{ //获取sql结果
if (sqlScript == "") return null;
//
OleDbCommand cmd = command;
if (cmd == null) cmd = getNewCommand();
OleDbTransaction trans = cmd.Transaction;
DataSet result = new DataSet();
OleDbDataAdapter da = null;
try
{
cmd.CommandText = sqlScript;
cmd.CommandType = CommandType.Text;
da = new OleDbDataAdapter(cmd);
//
da.Fill(result);
}
catch (Exception x)
{
globalErrorString = "[GetSqlResultDataSet-DataSet-command-1]获取SQl返回值出错!\r\n" + x.Message;
throw new Exception(globalErrorString);
result = null;
}
return result;
}
/// <summary>
/// 获取SQl返回值:数据集,返回DataSet。通过connection访问数据,用DataAdapter读取数据,填充到DataSet中
/// </summary>
/// <param name="connection">使用此连接</param>
/// <param name="sqlScript"></param>
/// <returns></returns>
public static DataSet getSqlResultDataSet(OleDbConnection connection, string sqlScript)
{ //获取sql结果
if (sqlScript == "") return null;
//
OleDbConnection conn = connection;
if (conn == null) conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]);
OleDbTransaction trans = null;
DataSet result = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(sqlScript, conn);
try
{
da.SelectCommand.Transaction = trans;
da.Fill(result);
}
catch (Exception x)
{
globalErrorString = "[GetSqlResultDataSet-DataSet-connection-2]获取SQl返回值出错!\r\n" + x.Message;
throw new Exception(globalErrorString);
result = null;
}
return result;
}
#endregion

#region//将DataReader的数据全部读入dataTable,dataReader2DataTabl
/// <summary>
/// 将DataReader的数据全部读入dataTable。注意:可以用lock锁定线程防止多人操作。 #if checked unchecked fixed lock System.Diagnostics.Process.Start("ipconfig /all");
/// </summary>
public static bool dataReader2DataTable(DbDataReader reader, ref DataTable table)
{ return dataReader2DataTable(reader, ref table, true); }
public static bool dataReader2DataTable(DbDataReader reader, ref DataTable table, bool lGatherData)
{
bool result = false;
int i = 0;
//
DbDataReader dr = reader;
DataRow row = null;
try
{
if (table == null) table = new DataTable();
//把数据读入到DataTable中:读取字段列表
table.Rows.Clear();
table.Columns.Clear();
for (i = 0; i < dr.FieldCount; i++)
table.Columns.Add(new DataColumn(dr.GetName(i), dr.GetFieldType(i)));
//把数据读入到DataTable中:读取字段值
if (lGatherData)
while (dr.Read())
{
row = table.NewRow();
for (i = 0; i < dr.FieldCount; i++) row[i] = dr[i];
table.Rows.Add(row);
}
//读取完毕
result = true;
}
catch (Exception x)
{ throw new Exception("[dataReader2DataTable]将OleDbDataReader值存入DataTable出错!" + x.Message); }
//
return result;
}
#endregion

#region //复制数据 copyDB
/// <summary>
/// 复制数据。
/// </summary>
/// <param name="dbFrom">数据来源</param>
/// <param name="dbTo">复制到哪里去</param>
/// <param name="lCheckColumn">是否检查有没有Column字段</param>
/// <returns>返回成功与否</returns>
public static bool copyDB(DataRow dbFrom, DataRow dbTo, bool lCheckColumn)
{ //复制
bool result = false, lHas = false;
DataColumnCollection colsFrom = null, colsTo = null;
try
{
//if (dbTo == null) { dbTo = dbTo.Table.NewRow(); dbTo.Table.Rows.Add(dbTo); }
//获取行的列清单
colsFrom = dbFrom.Table.Columns;
colsTo = dbTo.Table.Columns;
foreach (DataColumn colFrom in colsFrom)
{
lHas = !lCheckColumn;
if (lCheckColumn) foreach (DataColumn colTo in colsTo)
{ //循环检查目标有没有
lHas = (colTo.ColumnName.ToUpper() == colFrom.ColumnName.ToUpper());
if (lHas) break;
}
if (!lHas) continue; //忽略没有的字段
dbTo[colFrom.ColumnName] = dbFrom[colFrom.ColumnName]; //复制过去
}
//完成
result = true;
}
catch (Exception x)
{ throw new Exception("[copyDB]复制数据出错!\r\n" + x.Message); }
//返回
return result;
}
#endregion

#region //取传入数据对象的值,getFieldValue。数据对象可以是:DataReader、DataTable、DataRow、DataRowView
/// <summary>
/// 取传入对象的值,对象可以是:DataReader、DataTable、DataRow、DataRowView,会自动判断处理
/// </summary>
/// <param name="dbSource">数据源,类型可以是DataReader、DataTable、DataRow、DataRowView</param>
/// <param name="sField">字段</param>
/// <param name="oDefault">默认值</param>
/// <returns></returns>
public static object getFieldValue(object dbSource, string sField, object oDefault)
{ return getFieldValue(dbSource, sField, oDefault, false); }
public static object getFieldValue(object dbSource, string sField, object oDefault, bool lCheckFieldExist)
{ //取传入对象的值
object result = oDefault;
if (dbSource == null || string.IsNullOrEmpty(sField)) return oDefault;
//
object db = dbSource;
OleDbDataReader dr = null;
DataTable table = null;
DataRow row = null;
DataRowView drv = null;
//判断处理
try
{
if (db is DataTable)
{ //是dataTable,取第一行
table = db as DataTable;
if (table.Rows.Count > 0) row = table.Rows[0];
}
else if (db is DataRow)
{ //dataRow
row = db as DataRow;
}
else if (db is OleDbDataReader)
{ //是dataReader
dr = db as OleDbDataReader;
if (!dr.HasRows) return oDefault;
//dataReader2DataTable(dr, ref table);
//if (table.Columns.IndexOf(sField) == null) return oDefault;
return Gs_Class.tryNullTo(dr[sField], oDefault);
}
else if (db is DataRowView)
{ //DataRowView drv
drv = db as DataRowView;
return Gs_Class.tryNullTo(drv[sField], oDefault);
}

//取row值,取不到字段值不报错
if (row != null) return Gs_Class.tryNullTo(row[sField], oDefault);
}
catch (Exception x)
{
if (!lCheckFieldExist) throw; //不用检查字段是否存在,则报错
}
//
return result;
}
public static double getFieldValueNumber(object dbSource, string sField, double oDefault)
{
object o = getFieldValue(dbSource, sField, oDefault);
if (o == null || o is DBNull) return oDefault; else return Convert.ToDouble(o);
}
public static DateTime getFieldValueDateTime(object dbSource, string sField, DateTime oDefault)
{
object o = getFieldValue(dbSource, sField, oDefault);
if (o == null || o is DBNull) return oDefault; else return Convert.ToDateTime(o);
}
public static bool getFieldValueBool(object dbSource, string sField, bool oDefault)
{
object o = getFieldValue(dbSource, sField, oDefault);
if (o == null || o is DBNull) return oDefault; else return Convert.ToBoolean(o);
}
#endregion

#region //关联查询条件 linkFilter
/// <summary>
/// 关联查询条件
/// </summary>
/// <param name="sBaseFilter">原来的查询条件</param>
/// <param name="sFilterToAdd">要加到原来条件中的新条件</param>
/// <returns></returns>
public static bool linkFilter(ref string sBaseFilter, string sFilterToAdd)
{
if (string.IsNullOrEmpty(sFilterToAdd)) return true;
sBaseFilter += (string.IsNullOrEmpty(sBaseFilter) ? "" : " And ") + sFilterToAdd;
return true;
}
#endregion

#region//加密解密字符串,encryptString/decryptString
//加密字符串
public static string encryptString(string str)
{
return encryptString(str, nXor);
}
public static string encryptString(string str, int nXorParam)
{
return Gs_Class.encryptXor(str, nXorParam);
}
//解密字符串
public static string decryptString(string str)
{
return decryptString(str, nXor); //异或可逆
}
public static string decryptString(string str, int nXorParam)
{
return encryptString(str, nXorParam); //异或可逆
}
#endregion

#region//获取Request的值 getRequestValue
/// <summary>
/// 获取Request值,Request有明的和暗的Request.Form两种,此处首先尝试明的,再尝试暗的,都找不到则返回默认值""。
/// </summary>
/// <param name="sRequest">Request的名称</param>
/// <returns>返回Request值,为Null则返回默认值""</returns>
public static string getRequestValue(string sRequest)
{ //获取Request的值
return getRequestValue(sRequest, "");
}
/// <summary>
/// 获取Request值,Request有明的和暗的Request.Form两种,此处首先尝试明的,再尝试暗的,都找不到则返回默认值""。
/// </summary>
/// <param name="sRequest">Request的名称</param>
/// <param name="sDefault">默认值</param>
/// <returns>返回Request值,为Null则返回默认值""</returns>
public static string getRequestValue(string sRequest, string sDefault)
{ //获取Request的值
return getRequestValue(null, sRequest, sDefault);
}
/// <summary>
/// 获取Request值,Request有明的和暗的Request.Form两种,此处首先尝试明的,再尝试暗的,都找不到则返回默认值""。
/// </summary>
/// <param name="Request">HttpRequest,为null则默认为取HttpContext.Current.Request</param>
/// <param name="sRequest">参数名</param>
/// <param name="sDefault">默认值</param>
/// <returns>返回Request值,为Null则返回默认值""</returns>
public static string getRequestValue(HttpRequest Request, string sRequest, string sDefault)
{ //获取Request的值
if (Request == null) Request = HttpContext.Current.Request;
string result = Request[sRequest]; //明Request
if (string.IsNullOrEmpty(result)) result = Request.Form[sRequest]; //暗Request
if (string.IsNullOrEmpty(result)) result = sDefault;
if (string.IsNullOrEmpty(result)) result = "";
//转成中文处理,toChina
//byte[] buffer = Encoding.UTF8.GetBytes(result);
//result= Encoding.GetEncoding("utf-8").GetString(buffer);
//
return result;
}
/// <summary>
/// 获取Request值,包括明的和暗的,可以传入多个Request名字,比如参数命名不规范,有时写sShop=001,有时写Shop=001,用法:
/// sShop = Gs_DataFunction.getRequestValue(new string[] { "Shop", "sShop", "myShop" }, "")
/// </summary>
public static string getRequestValue(string[] requestArray, string sDefault) { return getRequestValueFirst(sDefault, requestArray); }
public static string getRequestValue(string[] requestArray) { return getRequestValue(requestArray, ""); }
/// <summary>
/// 获取Request值,包括明的和暗的,可以传入多个Request名字,比如参数命名不规范,有时写sShop=001,有时写Shop=001
/// 注意:params参数是活的,写几个都行,不写也行
/// </summary>
/// <param name="requestArray">可以传入多个Request名字,比如参数命名不规范,有时写sShop=001,有时写Shop=001</param>
/// <param name="sDefault">默认值</param>
/// <returns>返回获取到的值,取不到则返回默认值Default</returns>
public static string getRequestValueFirst(string sDefault, params string[] requestArray) { return getRequestValueFirst(null, sDefault, requestArray); }
public static string getRequestValueFirst(HttpRequest Request, string sDefault, params string[] requestArray)
{
string result = sDefault;
foreach (string sR in requestArray)
{
string s = getRequestValue(Request, sR, "");
if (!string.IsNullOrEmpty(s)) { result = s; break; } //找到了一个值
}
return result;
}
#endregion

#region //获取session值,GetSession,如果不存在 跳转到登录页重新登录
/// <summary> 获取session值 </summary>
/// <param name="key">Session的名称</param>
/// <returns>返回值</returns>
public static object GetSession(string key, string culture)
{
if (zhCN_Direct == "" && default_Direct != "") zhCN_Direct = default_Direct;
if (enGB_Direct == "" && default_Direct != "") enGB_Direct = default_Direct;
//
System.Web.SessionState.HttpSessionState Session = HttpContext.Current.Session;
object result = null;
result = Session[key];
//if (result==null && DebugMode) result = "Debug";
if (result == null && (!DebugMode))
{
// FormsAuthentication.SignOut();
if (string.IsNullOrEmpty(culture))
HttpContext.Current.Response.Redirect(default_Direct);
else if (culture.Contains("中文"))
HttpContext.Current.Response.Redirect(zhCN_Direct);
else
HttpContext.Current.Response.Redirect(enGB_Direct);
}
//
return result;
}

public static object GetSession(string key)
{
return GetSession(key, "");
}
public static string getSessionStr(string sKey) { return getSessionStr(sKey, ""); }
public static string getSessionStr(string sKey, string sDefault) { return Gs_Class.tryNullToString(HttpContext.Current.Session[sKey], sDefault).ToString(); }
public static string getUserID() { return getUserID("sUserID", ""); }
public static string getUserID(string sSessionKey, string culture)
{ //取用户号
object result = GetSession(sSessionKey, culture);
if (result == null) result = "";
return result.ToString();
}
#endregion


#region //读取系统设置 readSysConfig
/// <summary>
/// 读取系统设置,表GsConfig
/// </summary>
/// <param name="db">数据表</param>
/// <param name="sConfigName">配置名,对应sName字段</param>
/// <param name="sValueType">值类型,有S、N、D、O、L五种类型</param>
/// <param name="oDefault">返回值的默认值</param>
/// <returns>返回值,是sValue、nValue、dValue、lValue、oValue之一</returns>
public static object readSysConfig(DataTable db, string sConfigName, string sValueType, object oDefault)
{
object result = oDefault;
if (string.IsNullOrEmpty(sValueType)) sValueType = "";
//查找
foreach (DataRow dr in db.Rows) if (dr["sName"].ToString().ToUpper() == sConfigName.ToUpper())
{
result = getFieldValue(dr, sValueType + "Value", oDefault);
break;
}
//完成
return result;
}
/// <summary>
/// 读取系统设置,表GsConfig
/// </summary>
/// <param name="cmd">ole命令组件,可以携带事务</param>
/// <param name="sConfigName">配置名,对应sName自动</param>
/// <param name="sValueType">值类型,有S、N、D、O、L五种类型</param>
/// <param name="oDefault">默认值</param>
/// <returns>返回值,是sValue、nValue、dValue、lValue、oValue之一</returns>
public static object readSysConfig(OleDbCommand cmd, string sConfigName, string sValueType, object oDefault)
{
object result = oDefault;
if (string.IsNullOrEmpty(sValueType)) sValueType = "S";
result = Gs_DataFunction.getSqlResult("select " + sValueType + "Value from gsConfig where sName='" + Gs_Class.removeSQLAttachStr(sConfigName) + "' ", oDefault, cmd);
if (result == null) return oDefault; else return result;
}
#endregion


#region //写入系统配置 writeSysConfig
/// <summary>
/// 写入系统配置
/// </summary>
/// <param name="db">数据表</param>
/// <param name="sConfigName">配置名,对应sName字段</param>
/// <param name="oValue">值,是sValue、nValue、dValue、lValue、oValue字段之一</param>
/// <param name="sValueType">值类型,对应sType字段,有S、N、D、O、L五种类型</param>
/// <returns>返回成功与否</returns>
public static bool writeSysConfig(DataTable db, string sConfigName, object oValue, string sValueType)
{
bool result = false;
DataRow dr = null;
if (string.IsNullOrEmpty(sValueType)) sValueType = "s";
//查找有无此配置
foreach (DataRow r in db.Rows) if (r["sName"].ToString().ToUpper() == sConfigName.ToUpper())
{ //查找到了
dr = r;
break;
}
//找不到
if (dr == null)
{
dr = db.NewRow(); //加一个行
initializeRecord(dr); //初始化新增加的行
db.Rows.Add(dr);
dr["sName"] = sConfigName;
setDbValue(dr, "lEnable", true);
setDbValue(dr, "dCreate", DateTime.Now);
}
//写入
dr["sType"] = sValueType;
dr[sValueType + "Value"] = oValue;
//完成
return result;
}
/// <summary>
/// 写入系统配置
/// </summary>
/// <param name="cmd">ole命令组件</param>
/// <param name="sConfigName">配置名,对应sName字段</param>
/// <param name="oValue">值,是sValue、nValue、dValue、lValue、oValue字段之一</param>
/// <param name="sValueType">值类型,对应sType字段,有S、N、D、O、L五种类型</param>
/// <returns>返回成功与否</returns>
public static bool writeSysConfig(OleDbCommand cmd, string sConfigName, object oValue, string sValueType)
{
bool result = false;
//准备
OleDbDataAdapter da = null;
DataTable db = null;
string sql = "select * from gsConfig where sName='" + Gs_Class.removeSQLAttachStr(sConfigName) + "' ";
Gs_DataFunction.getDataAdapter(cmd, sql, ref da, ref db);
//写入
result = writeSysConfig(db, sConfigName, oValue, sValueType);
da.Update(db);
//完成
return result;
}
#endregion


#region//获取语言标志 getLanguageSign
public static string getLanguageSign(string Culture)
{
if (Culture.Contains("中文")) return ""; else return "En";
}
#endregion

#region //CShare的Asc函数。高级AscAdv
/// <summary>
/// C#的Asc函数。高级AscAdv
/// </summary>
/// <param name="s">字符Char</param>
/// <returns>其Asc值</returns>
public static short AscAdv(char s)
{
byte[] bytes = System.Text.Encoding.GetEncoding("gb2312").GetBytes(s.ToString());
if (bytes.Length == 2)
{
return (short)((bytes[0] << 8) + bytes[1]);
}
else
return bytes[0];
}
#endregion

#region//setDropdownValue 页面上的dropDown,选择之后,检查如果有SelectedID就选上,没有则首先检查大小写,大小写也没有,再送数据库中搜索一遍,找到了加上listItem并选定
/// <summary>
/// 页面上的dropDown,选择之后,检查如果有SelectedID就选上,没有则首先检查大小写,大小写也没有,再送数据库中搜索一遍,找到了加上listItem并选定
/// </summary>
public static bool setDropdownValue(DropDownList cbx, string sIDValue)
{
bool result = false, lEnable = cbx.Enabled;
if (!lEnable) cbx.Enabled = true;
string sID = sIDValue;
int i = 0;
//是空值,直接选择上
if (string.IsNullOrEmpty(sIDValue) || sIDValue.Trim() == "")
{
if (cbx.Items.FindByValue("") == null) cbx.Items.Insert(0, new ListItem("", ""));
cbx.SelectedValue = ""; //直接选择上
result = true;
}
else if (cbx.Items.FindByValue(sID) != null) { cbx.SelectedValue = sID; result = true; }
else if (cbx.Items.FindByValue(sID.ToUpper()) != null) { cbx.SelectedValue = sID.ToUpper(); result = true; }
else if (cbx.Items.FindByValue(sID.ToLower()) != null) { cbx.SelectedValue = sID.ToLower(); result = true; }
else //逐个检查大小写
{
for (i = 0; i < cbx.Items.Count; i++) if (cbx.Items[i].Value.ToString().ToUpper() == sID.ToUpper()) { cbx.SelectedIndex = i; result = true; break; }
}
if (!result) //还是没有
{
sID = sID.ToUpper();
if (sID == "TRUE" || sID == "FALSE")
{ //如果是逻辑型的
if (sID.ToUpper() == "TRUE") sID = "1"; else if (sID.ToUpper() == "FALSE") sID = "0";
if (cbx.Items.FindByValue(sID) != null) { cbx.SelectedValue = sID; result = true; }
}
}
//
if (cbx.Enabled != lEnable) cbx.Enabled = lEnable;
return result;
}
public static bool setDropdownValue(DropDownList cbx, string sIDValue, string sTableToFind, OleDbConnection connection)
{
return setDropdownValue(cbx, sIDValue, sTableToFind, "", "", connection);
}
public static bool setDropdownValue(DropDownList cbx, string sIDValue, string sTableToFind, string sIDField, string sNameField, OleDbConnection connection)
{
OleDbConnection conn = connection;
/*if (conn == null)*/
conn = new OleDbConnection(ConfigurationManager.AppSettings["ConnectionString"]);
OleDbCommand cmd = new OleDbCommand("", conn);
return setDropdownValue(cbx, sIDValue, sTableToFind, sIDField, sNameField, cmd);
}
/// <summary>
/// 页面上的dropDown,选择之后,检查如果有SelectedID就选上,没有则首先检查大小写,大小写也没有,再送数据库中搜索一遍,找到了加上listItem并选定
/// </summary>
public static bool setDropdownValue(DropDownList cbx, string sIDValue, string sTableToFind, string sIDField, string sNameField, OleDbCommand command)
{
if (cbx == null) return false;
bool result = false, lConn = false, lEnable = cbx.Enabled;
//
int i = 0;
string s = Gs_Class.removeSQLAttachStr(sIDValue), sID = sIDField, sName = sNameField, sql = "", sObjName = cbx.ID;
if (string.IsNullOrEmpty(sID)) sID = "sID";
if (string.IsNullOrEmpty(sName)) sName = "sName";
sql = "select " + sID + " as sID, " + sName + " as sName from " + sTableToFind + " where 1=1 And " + sID + "='" + s + "' ";
sID = s;
//先调用大小写检查的
if (setDropdownValue(cbx, sID)) return true;
//
ListItem itm = null;
OleDbCommand cmd = command;
OleDbConnection conn = null;
OleDbDataReader dr = null;
//第一步:检查是否有了,有则直接选上
try
{
if (!lEnable) cbx.Enabled = true; //临时设置为有效
//////////////////从数据库中查找//////////////////
if (string.IsNullOrEmpty(sTableToFind)) goto lbl_iNone; //throw new Exception("找不到编号[" + sIDValue + "],查找表名非法!中止。");
//
Gs_DataFunction.getDataCommand(cmd, ref conn, ref cmd);
cmd.CommandText = sql;
lConn = conn.State == ConnectionState.Open;
if (!lConn) conn.Open();
//打开数据集
dr = cmd.ExecuteReader();
if (dr.Read())
{ //找到了,则加上此项,并选择上
cbx.Items.Add(new ListItem(dr["sName"].ToString(), sID.ToUpper()));
cbx.SelectedIndex = cbx.Items.Count - 1;
result = true;
goto lbl_iEnd;
}
lbl_iNone:
//throw new Exception("尝试大小写、数据库都找不到编号[" + sID + "]");
itm = new ListItem("【" + sID + "】", sID); //找不到此编号
cbx.Items.Add(itm);
cbx.SelectedValue = sID;
lbl_iEnd:
i++;
}
catch (Exception x)
{
Gs_DataFunction.globalErrorString = "[setDropdownValue]处理" + sObjName + "选取值出错!\r\n" + x.Message;
throw new Exception(Gs_DataFunction.globalErrorString);
}
finally
{
if (cbx.Enabled != lEnable) cbx.Enabled = lEnable;
if (dr != null) dr.Close();
if (!lConn && conn!=null) conn.Close();
}
//完毕,返回值
return result;
}
#endregion

#region//生成一个新的连接 getNewConnection,连接字符串默认为sConnectionString
public static OleDbConnection getNewConnection(string sConfigName)
{ //生成一个新的连接
string sCon = sConfigName;
if (string.IsNullOrEmpty(sCon)) sCon = "ConnectionString";
/*if (string.IsNullOrEmpty(sConnectionString))*/
sConnectionString = Gs_Class.tryNullToString(ConfigurationManager.AppSettings[sCon], "");
return new OleDbConnection(sConnectionString);
}
public static OleDbConnection getNewConnection() { return getNewConnection(""); }
#endregion

#region //生成一个新的数据命令组件,getNewCommand
public static OleDbCommand getNewCommand() { return new OleDbCommand("", getNewConnection()); }
#endregion


}
}

转载于:https://www.cnblogs.com/HaiHong/p/5217486.html

以下代码哪里定义了查询功能: *&---------------------------------------------------------------------* *& REPORT ZPM_YZ_BPBJLONG3 *& *&---------------------------------------------------------------------* *& *& *&---------------------------------------------------------------------* REPORT zmal. TABLES:zqm_wlz_yz,makt,mara,zmal,zpm_cs_mal_st. DATA ok_code TYPE sy-ucomm . DATA save_ok TYPE sy-ucomm . CLASS lcl_application DEFINITION DEFERRED . DATA custom_container TYPE REF TO cl_gui_custom_container . DATA gcontainer TYPE REF TO cl_gui_custom_container . DATA tree_control TYPE REF TO cl_gui_simple_tree . DATA grid TYPE REF TO cl_gui_alv_grid . DATA gs_layout TYPE lvc_s_layo. DATA gt_fieldcat TYPE STANDARD TABLE OF lvc_s_fcat . DATA gw_fieldcat LIKE LINE OF gt_fieldcat . DATA node_table LIKE TABLE OF mtreesnode . DATA node1 TYPE mtreesnode . DATA: BEGIN OF st_vbak OCCURS 0, matkl LIKE zqm_wlz_yz-matkl, num1 LIKE zqm_wlz_yz-num1, num2 LIKE zqm_wlz_yz-num2, num3 LIKE zqm_wlz_yz-num3, num(1) , END OF st_vbak. DATA: n1 LIKE zqm_wlz_yz-num1, n2 LIKE zqm_wlz_yz-num2, n3 LIKE zqm_wlz_yz-num3. DATA:t_vbak LIKE st_vbak OCCURS 0 WITH HEADER LINE. DATA:w_vbak LIKE t_vbak OCCURS 0 WITH HEADER LINE. DATA g_application TYPE REF TO lcl_application . **************************************************************************************** *ALV用到的类库 TYPE-POOLS:slis. DATA: wa_alv_filed TYPE slis_fieldcat_alv, "列描述 wa_alv_filedcat TYPE slis_t_fieldcat_alv. "列描述内表,列清单 DATA: BEGIN OF mdezx OCCURS 0. INCLUDE STRUCTURE mdez. DATA: END OF mdezx. DATA: BEGIN OF mdpsx OCCURS 0. INCLUDE STRUCTURE mdps. DATA: END OF mdpsx. DATA: BEGIN OF mdsux OCCURS 0. INCLUDE STRUCTURE mdsu. DATA: END OF mdsux. DATA: BEGIN OF i_zqm OCCURS 0. INCLUDE STRUCTURE zqm_wlz_yz. DATA: END OF i_zqm. DATA:BEGIN OF itabb OCCURS 0, edmxcdm(30) TYPE c, edmxcsm(20) TYPE c, ztext(30) TYPE c, box TYPE char01, END OF itabb. * DATA: BEGIN OF t_zmal OCCURS 0, matnr LIKE mard-matnr, "物料号 tlines LIKE zmal-tlines, "物料描述 mtart LIKE mara-mtart, "物料类型 matkl LIKE mara-matkl, lgort LIKE mard-lgort, " 库存地点 bismt LIKE mara-bismt, "库格 meins LIKE mara-meins, "单位 eisbe LIKE marc-eisbe, "安全库存 labst LIKE mard-labst, "非限制库存 open_po LIKE mdez-mng01, "在途库存 bstmi LIKE marc-bstmi, "最小采购量 bstfe LIKE marc-bstfe, "固定采购量 bdmng LIKE resb-bdmng, labst1 LIKE mard-labst, werks LIKE mard-werks, END OF t_zmal. DATA:BEGIN OF z_mal OCCURS 0, matnr LIKE zpm_yz_mal_st-matnr, lgort LIKE zpm_yz_mal_st-lgort, werks LIKE zpm_yz_mal_st-werks, bismt LIKE zpm_yz_mal_st-bismt, END OF z_mal. DATA:t_zmal1 LIKE t_zmal OCCURS 0 WITH HEADER LINE. DATA t_vbap LIKE STANDARD TABLE OF t_zmal. DATA: v_vbap LIKE LINE OF t_vbap. DATA: zmatnr TYPE zpm_yz_mal-matnr, ztlines TYPE zpm_yz_mal-tlines, zkw TYPE mard-lgort, zkg TYPE zpm_yz_mal_st-bismt. DATA: ztlines1 TYPE zmal-tlines. DATA: ztlines2 TYPE zmal-tlines. DATA: ztlines3 TYPE zmal-tlines. DATA: zkg1 LIKE zpm_yz_mal_st-bismt. DATA: zkg2 LIKE zpm_yz_mal_st-bismt. DATA: zkg3 LIKE zpm_yz_mal_st-bismt. DATA:i1(1),i2(1),i3(1). DATA:fxk01(1). *----------------------------------------------------------------------* * CLASS LCL_APPLICATION DEFINITION *----------------------------------------------------------------------* **----------------------------------------------------------------------* CLASS lcl_application DEFINITION . PUBLIC SECTION . METHODS handle_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree IMPORTING node_key . ENDCLASS . "LCL_APPLICATION DEFINITION *----------------------------------------------------------------------* * CLASS LCL_APPLICATION IMPLEMENTATION *------------------------------------------ *----------------------------* * *----------------------------------------------------------------------* CLASS lcl_application IMPLEMENTATION . METHOD handle_selection_changed . READ TABLE node_table WITH KEY node_key = node_key INTO node1 . PERFORM get_data_grid USING node_key node1-relatkey node1-n_image. CALL METHOD grid->refresh_table_display. ENDMETHOD . "HANDLE_SELECTION_CHANGED ENDCLASS . "LCL_APPLICATION IMPLEMENTATION * SELECTION-SCREEN BEGIN OF BLOCK A WITH FRAME TITLE TEXT-001 . * PARAMETERS P_VKORG TYPE TVKOT-VKORG OBLIGATORY DEFAULT '2030'. * PARAMETERS P_VTWEG TYPE TVTWT-VTWEG OBLIGATORY DEFAULT '11'. * SELECTION-SCREEN END OF BLOCK A . START-OF-SELECTION . PERFORM get_data . CREATE OBJECT g_application. CALL SCREEN 0100 . *----------------------------------------------------------------------* * MODULE STATUS_0100 OUTPUT *----------------------------------------------------------------------* * *------------ *----------------------------------------------------------* MODULE status_0100 OUTPUT . SET PF-STATUS '0100'. IF tree_control IS INITIAL. PERFORM create_tree . ENDIF. ENDMODULE . "STATUS_0100 OUTPUT *----------------------------------------------------------------------* * MODULE USER_COMMAND_0100 INPUT *----------------------------------------------------------------------* * *----------------------------------------------------------------------* MODULE user_command_0100 INPUT . save_ok = ok_code . CLEAR ok_code . CASE save_ok. WHEN 'BACK'. SET SCREEN 0. * CLEAR ITABB. * FREE ITABB. WHEN 'EXIT'. LEAVE PROGRAM. WHEN OTHERS. ENDCASE. ENDMODULE . "USER_COMMAND_0100 INPUT *&---------------------------------------------------------------------**& FORM *CREATE_TREE *&---------------------------------------------------------------------* * TEXT *----------------------------------------------------------------------* * --> P1 TEXT * <-- P2 TEXT *----------------------------------------------------------------------* FORM create_tree . DATA events TYPE cntl_simple_events . DATA event1 TYPE cntl_simple_event . DATA num(1). DATA num1 LIKE zqm_wlz_yz-num1 . DATA num2 LIKE zqm_wlz_yz-num2 . DATA num3 LIKE zqm_wlz_yz-num3 . DATA matkl LIKE zqm_wlz_yz-matkl . DATA l_txt LIKE zqm_wlz_yz-txt1. DATA l_txt1 LIKE zqm_wlz_yz-txt1. DATA l_txt2 LIKE zqm_wlz_yz-txt2 . DATA l_txt3 LIKE zqm_wlz_yz-txt3 . DATA str1(255) . CREATE OBJECT custom_container EXPORTING container_name = 'TREE'. CREATE OBJECT tree_control EXPORTING parent = custom_container node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single. CREATE OBJECT gcontainer EXPORTING container_name = 'GCONTAINER'. CREATE OBJECT grid EXPORTING i_parent = gcontainer. PERFORM frm_write_data. gs_layout-grid_title = '物料显示' . * GS_LAYOUT-CWIDTH_OPT = 'X' . gs_layout-zebra = 'X' . * CONCATENATE P_VKORG P_VTWEG INTO NODE1-NODE_KEY . * NODE1-RELATKEY = P_VKORG . PERFORM get_data_grid USING node1-node_key node1-relatkey node1-n_image . * CALL METHOD grid->set_table_for_first_display EXPORTING is_layout = gs_layout CHANGING it_fieldcatalog = gt_fieldcat it_outtab = t_vbap. LOOP AT t_vbak INTO w_vbak. CLEAR l_txt . CLEAR l_txt1 . CLEAR l_txt2 . CLEAR l_txt3 . l_txt = '物料分类'. *-----ECCUpgradeS4--------AB_ZACK--------20221028--------START * SELECT SINGLE * txt1 * INTO l_txt1 * FROM zqm_wlz_yz * WHERE num1 = w_vbak-num1 . * * SELECT SINGLE * txt2 * INTO l_txt2 * FROM zqm_wlz_yz * WHERE num1 = w_vbak-num1 AND num2 = w_vbak-num2. * SELECT SINGLE * txt3 * INTO l_txt3 * FROM zqm_wlz_yz * WHERE num1 = w_vbak-num1 AND num2 = w_vbak-num2 AND num3 = w_vbak-num3. SELECT txt1 INTO l_txt1 FROM zqm_wlz_yz UP TO 1 ROWS WHERE num1 = w_vbak-num1 ORDER BY PRIMARY KEY.ENDSELECT. SELECT txt2 INTO l_txt2 FROM zqm_wlz_yz UP TO 1 ROWS WHERE num1 = w_vbak-num1 AND num2 = w_vbak-num2 ORDER BY PRIMARY KEY. ENDSELECT. SELECT txt3 INTO l_txt3 FROM zqm_wlz_yz UP TO 1 ROWS WHERE num1 = w_vbak-num1 AND num2 = w_vbak-num2 AND num3 = w_vbak-num3 ORDER BY PRIMARY KEY. ENDSELECT. *-----ECCUpgradeS4--------ABA_ZACK--------20221028--------END "在创建根节点的同时需要创建下级以及次级子节点 IF num NE w_vbak-num . CLEAR node1 . node1-node_key = w_vbak-num . "FIRST LAYER CLEAR node1-relatkey . CLEAR node1-relatship . "SET THE ICON AS FOLDER node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . "CLEAR THE ICON OF THE NODE CLEAR node1-n_image . CLEAR node1-exp_image . node1-expander = 'X'. * NODE1-TEXT = L_TXT1 . node1-text = l_txt . APPEND node1 TO node_table . ************************************************************** CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 INTO node1-node_key . node1-relatkey = w_vbak-num . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . CLEAR node1-n_image . CLEAR node1-exp_image . node1-expander = 'X'. "DISPLAY THE NODE VTWEG * NODE1-TEXT = L_TXT2 . CONCATENATE w_vbak-num1 l_txt1 INTO node1-text . APPEND node1 TO node_table . ************************************************************************** CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 INTO node1-node_key . CONCATENATE w_vbak-num w_vbak-num1 INTO str1 . node1-relatkey = str1 . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . CLEAR node1-n_image . CLEAR node1-exp_image . node1-expander = 'X'. "DISPLAY THE NODE VTWEG * NODE1-TEXT = L_TXT2 . CONCATENATE w_vbak-num2 l_txt2 INTO node1-text . APPEND node1 TO node_table . ************************************************************************ CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 w_vbak-num3 INTO node1-node_key. CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 INTO str1 . node1-relatkey = str1 . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . node1-n_image = '@5B@' . node1-exp_image = '@5B@' . node1-expander = 'X'. * NODE1-TEXT = W_VBAK-NUM3 . CONCATENATE w_vbak-num3 l_txt3 INTO node1-text . APPEND node1 TO node_table . ENDIF. "在创建次级节点的同时需要创建其字节点 IF ( num = w_vbak-num ) AND ( num1 <> w_vbak-num1 ). CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 INTO node1-node_key . node1-relatkey = w_vbak-num . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . CLEAR node1-n_image . CLEAR node1-exp_image . node1-expander = 'X'. "DISPLAY THE NODE VTWEG * NODE1-TEXT = L_TXT2 . CONCATENATE w_vbak-num1 l_txt1 INTO node1-text . APPEND node1 TO node_table . ************************************************************************** CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 INTO node1-node_key . CONCATENATE w_vbak-num w_vbak-num1 INTO str1 . node1-relatkey = str1 . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . CLEAR node1-n_image . CLEAR node1-exp_image . node1-expander = 'X'. "DISPLAY THE NODE VTWEG * NODE1-TEXT = L_TXT2 . CONCATENATE w_vbak-num2 l_txt2 INTO node1-text . APPEND node1 TO node_table . ************************************************************************ CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 w_vbak-num3 INTO node1-node_key. CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 INTO str1 . node1-relatkey = str1 . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . node1-n_image = '@5B@' . node1-exp_image = '@5B@' . node1-expander = 'X'. * NODE1-TEXT = W_VBAK-NUM3 . CONCATENATE w_vbak-num3 l_txt3 INTO node1-text . APPEND node1 TO node_table . ENDIF. "在创建次级节点的同时需要创建其字节点 IF ( num = w_vbak-num ) AND ( num1 = w_vbak-num1 ) AND num2 <> w_vbak-num2. CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 INTO node1-node_key . CONCATENATE w_vbak-num w_vbak-num1 INTO str1 . node1-relatkey = str1 . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . CLEAR node1-n_image . CLEAR node1-exp_image . node1-expander = 'X'. "DISPLAY THE NODE VTWEG * NODE1-TEXT = L_TXT2 . CONCATENATE w_vbak-num2 l_txt2 INTO node1-text . APPEND node1 TO node_table . ************************************************************************ CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 w_vbak-num3 INTO node1-node_key. CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 INTO str1 . node1-relatkey = str1 . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . node1-n_image = '@5B@' . node1-exp_image = '@5B@' . node1-expander = 'X'. * NODE1-TEXT = W_VBAK-NUM3 . CONCATENATE w_vbak-num3 l_txt3 INTO node1-text . APPEND node1 TO node_table . ENDIF. IF ( num = w_vbak-num ) AND ( num1 = w_vbak-num1 ) AND num2 = w_vbak-num2 AND num3 <> w_vbak-num3. CLEAR node1 . CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 w_vbak-num3 INTO node1-node_key. CONCATENATE w_vbak-num w_vbak-num1 w_vbak-num2 INTO str1 . node1-relatkey = str1 . node1-relatship = cl_gui_simple_tree=>relat_last_child . node1-hidden = '' . node1-disabled = '' . node1-isfolder = 'X' . node1-n_image = '@5B@' . node1-exp_image = '@5B@' . node1-expander = 'X'. * NODE1-TEXT = W_VBAK-NUM3 . CONCATENATE w_vbak-num3 l_txt3 INTO node1-text . APPEND node1 TO node_table . ENDIF. num = w_vbak-num. num1 = w_vbak-num1 . num2 = w_vbak-num2 . num3 = w_vbak-num3 . matkl = w_vbak-matkl . ENDLOOP. CALL METHOD tree_control->add_nodes EXPORTING table_structure_name = 'MTREESNODE' node_table = node_table EXCEPTIONS error_in_node_table = 1 failed = 2 dp_error = 3 table_structure_name_not_found = 4 OTHERS = 5. * EVENT1-EVENTID = CL_GUI_SIMPLE_TREE=>EVENTID_NODE_DOUBLE_CLICK . * EVENT1-APPL_EVENT = 'X' . * APPEND EVENT1 TO EVENTS . event1-eventid = 21 . event1-appl_event = 'X' . APPEND event1 TO events . CALL METHOD tree_control->set_registered_events EXPORTING events = events EXCEPTIONS cntl_error = 1 cntl_system_error = 2 illegal_event_combination = 3 OTHERS = 4. SET HANDLER g_application->handle_selection_changed FOR tree_control . ENDFORM. " CREATE_TREE *316 *&---------------------------------------------------------------------* *317 *& FORM GET_DATA *318 *&---------------------------------------------------------------------* *319 * TEXT *320 *----------------------------------------------------------------------* *321 * --> P1 TEXT *322 * <-- P2 TEXT *323 *----------------------------------------------------------------------* FORM get_data . SELECT matkl num1 num2 num3 INTO TABLE t_vbak FROM zqm_wlz_yz . IF sy-subrc = 0. LOOP AT t_vbak. t_vbak-num = '1'. MODIFY t_vbak. ENDLOOP. ENDIF. SORT t_vbak BY num matkl . ENDFORM. " GET_DATA *336 *&---------------------------------------------------------------------* *337 *& FORM GET_DATA_GRID *338 *&---------------------------------------------------------------------* *339 * TEXT *340 *----------------------------------------------------------------------* *341 * -->P_NODEKEY TEXT *342 *----------------------------------------------------------------------* FORM get_data_grid USING p_nodekey p_relatkey p_image. DATA: n1 LIKE zqm_wlz_yz-num1, n2 LIKE zqm_wlz_yz-num2, n3 LIKE zqm_wlz_yz-num3. DATA: l_len1 TYPE i. DATA: l_len2 TYPE i. DATA: l_len3 TYPE i. DATA: l_len11 TYPE i. DATA: l_len22 TYPE i. DATA:l1 LIKE node1-relatkey. DATA:l2 LIKE node1-node_key. DATA: dynpfields TYPE TABLE OF dynpread WITH HEADER LINE. CLEAR:zkg1,zkg2,zkg3,ztlines1,ztlines2,ztlines3. CLEAR: dynpfields, dynpfields[]. dynpfields-fieldname = 'ZKW'. "填入需要读值的字段名 APPEND dynpfields. CALL FUNCTION 'DYNP_VALUES_READ' EXPORTING dyname = sy-repid dynumb = sy-dynnr translate_to_upper = 'X' TABLES dynpfields = dynpfields EXCEPTIONS OTHERS = 9. IF sy-subrc = 0. READ TABLE dynpfields WITH KEY fieldname = 'ZKW'. zkw = dynpfields-fieldvalue. "备注 ENDIF. CLEAR: dynpfields, dynpfields[]. dynpfields-fieldname = 'ZTLINES'. "填入需要读值的字段名 APPEND dynpfields. CALL FUNCTION 'DYNP_VALUES_READ' EXPORTING dyname = sy-repid dynumb = sy-dynnr translate_to_upper = 'X' TABLES dynpfields = dynpfields EXCEPTIONS OTHERS = 9. IF sy-subrc = 0. READ TABLE dynpfields WITH KEY fieldname = 'ZTLINES'. ztlines = dynpfields-fieldvalue. "备注 ENDIF. IF p_nodekey = '1' AND p_relatkey = ''. p_nodekey = ''. IF zmatnr <> ''. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' "AND MARA~MTART = 'ERSA' "and ( mard~lgort = 'WL01' or mard~lgort = 'MT01') AND mara~matkl <> '' AND mard~matnr = zmatnr. LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' * AND MARA~MATKL <> '' AND MARA~MATNR = ZMATNR. ELSE. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' AND mara~mtart = 'ERSA' " and ( mard~lgort = 'WL01' or mard~lgort = 'MT01' ) AND mara~matkl <> ''. LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. " SELECT MARA~MATNR " MARA~MTART " MARA~BISMT " MARA~MEINS " INTO CORRESPONDING FIELDS OF TABLE T_ZMAL " FROM MARC " INNER JOIN MARA ON MARA~MATNR = MARC~MATNR " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL " WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' " AND MARA~MATKL <> '' . ENDIF. ELSEIF p_relatkey <> ''. l_len11 = strlen( p_relatkey ) . l_len11 = l_len11 - 1. IF l_len11 <= 0. l1 = ''. ELSE. l1 = p_relatkey+1(l_len11). ENDIF. p_relatkey = l1. l_len22 = strlen( p_nodekey ). l_len22 = l_len22 - 1. IF l_len22 <= 0. l2 = ''. ELSE. l2 = p_nodekey+1(l_len22). ENDIF. p_nodekey = l2. ENDIF. IF p_nodekey = '' AND p_relatkey = '' AND p_image = ''. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '' * AND MARA~MATKL <> ''. ELSEIF p_relatkey IS INITIAL AND p_nodekey <> ''. IF zmatnr <> ''. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' AND mara~mtart = 'ERSA' " and ( mard~lgort = 'WL01' or mard~lgort = 'MT01' ) " AND ZQM_WLZ_YZ~NUM1 = P_NODEKEY AND mara~matkl <> '' AND mard~matnr = zmatnr. LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl num1 = p_nodekey. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' * AND MARA~MATNR = ZMATNR * AND ZQM_WLZ_YZ~NUM1 = P_NODEKEY * AND MARA~MATKL <> ''. ELSE. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' AND mara~mtart = 'ERSA' " and ( mard~lgort = 'WL01' or mard~lgort = 'MT01' ) " AND ZQM_WLZ_YZ~NUM1 = P_NODEKEY AND mara~matkl <> '' . LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl num1 = p_nodekey. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' AND * ZQM_WLZ_YZ~NUM1 = P_NODEKEY * AND MARA~MATKL <> ''. ENDIF. ELSE. IF p_image IS INITIAL. l_len1 = strlen( p_nodekey ). l_len2 = strlen( p_relatkey ). l_len3 = l_len1 - l_len2. n1 = p_nodekey+l_len2(l_len3). IF zmatnr <> ''. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' AND mara~mtart = 'ERSA' " and ( mard~lgort = 'WL01' or mard~lgort = 'MT01' ) " AND ZQM_WLZ_YZ~NUM1 = P_RELATKEY " AND ZQM_WLZ_YZ~NUM2 = N1 AND mara~matkl <> '' AND mard~matnr = zmatnr. LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl num1 = p_relatkey num2 = n1. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' AND * MARA~MATNR = ZMATNR AND * ZQM_WLZ_YZ~NUM1 = P_RELATKEY * AND ZQM_WLZ_YZ~NUM2 = N1 * AND MARA~MATKL <> ''. ELSE. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' AND mara~mtart = 'ERSA' " and ( mard~lgort = 'WL01' or mard~lgort = 'MT01' ) * AND ZQM_WLZ_YZ~NUM1 = P_RELATKEY * AND ZQM_WLZ_YZ~NUM2 = N1 AND mara~matkl <> ''. LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl num1 = p_relatkey num2 = n1. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' AND * ZQM_WLZ_YZ~NUM1 = P_RELATKEY * AND ZQM_WLZ_YZ~NUM2 = N1 * AND MARA~MATKL <> ''. ENDIF. ELSE. IF zmatnr <> ''. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' AND mara~mtart = 'ERSA' " and ( mard~lgort = 'WL01' or mard~lgort = 'MT01' ) " AND ZQM_WLZ_YZ~MATKL = P_NODEKEY AND mara~matkl <> '' AND mard~matnr = zmatnr. LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl . IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. IF t_zmal-matkl <> p_nodekey. DELETE t_zmal. ENDIF. ENDLOOP. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' AND * MARA~MATNR = ZMATNR AND * ZQM_WLZ_YZ~MATKL = P_NODEKEY * AND MARA~MATKL <> ''. ELSE. SELECT mard~matnr "物料号 mara~mtart "物料类型 mard~lgort " 库存地点 mara~meins "单位 mara~matkl "物料组 marc~eisbe "安全库存 marc~bstmi "最小采购量 marc~bstfe "固定采购量 mard~labst "非限制库存 mara~bismt "库格 mard~werks INTO CORRESPONDING FIELDS OF TABLE t_zmal FROM mard INNER JOIN marc ON marc~matnr = mard~matnr AND marc~werks = mard~werks INNER JOIN mara ON mara~matnr = mard~matnr " INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL WHERE ( mard~werks = '1011' OR ( mard~werks = '1010' AND mard~lgort = 'EL01' ) ) AND mara~mstae <> '01' AND mara~mtart = 'ERSA' " and ( mard~lgort = 'WL01' or mard~lgort = 'MT01') " AND ZQM_WLZ_YZ~MATKL = P_NODEKEY AND mara~matkl <> '' . LOOP AT t_zmal. IF t_zmal-matkl(1) = 'S' . t_zmal-matkl+0(1) = '0'. MODIFY t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. READ TABLE t_vbak WITH KEY matkl = t_zmal-matkl. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. LOOP AT t_zmal. IF t_zmal-matkl <> p_nodekey. DELETE t_zmal. ENDIF. ENDLOOP. * SELECT MARA~MATNR * MARA~MTART * MARA~BISMT * MARA~MEINS * * INTO CORRESPONDING FIELDS OF TABLE T_ZMAL * FROM MARC * INNER JOIN MARA ON MARA~MATNR = MARC~MATNR * INNER JOIN ZQM_WLZ_YZ ON ZQM_WLZ_YZ~MATKL = MARA~MATKL * WHERE MARC~WERKS = '7010' AND MARA~MSTAE <> '01' AND MARA~MTART = 'ERSA' AND * ZQM_WLZ_YZ~MATKL = P_NODEKEY * AND MARA~MATKL <> ''. ENDIF. ENDIF. ENDIF. IF zkw <> ''. LOOP AT t_zmal. IF t_zmal-lgort <> zkw. DELETE t_zmal. ENDIF. ENDLOOP. ENDIF. *LOOP AT T_ZMAL. * *SELECT MATNR * LGORT * WERKS * BISMT * INTO CORRESPONDING FIELDS OF TABLE Z_MAL * FROM ZPM_YZ_MAL_ST * WHERE WERKS = '1010' AND MATNR = T_ZMAL-MATNR AND LGORT = T_ZMAL-LGORT. * IF SY-SUBRC = 0. * LOOP AT Z_MAL . * IF T_ZMAL-BISMT = '' . * CONCATENATE '/' Z_MAL-BISMT INTO T_ZMAL-BISMT. * ELSE. * CONCATENATE T_ZMAL-BISMT '/' Z_MAL-BISMT INTO T_ZMAL-BISMT. * ENDIF. * * ENDLOOP. * MODIFY T_ZMAL. * ENDIF. * *ENDLOOP. IF zkg <> ''. LOOP AT t_zmal. SEARCH t_zmal-bismt FOR zkg. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDLOOP. ENDIF. * IF SY-SUBRC <> 0. * MESSAGE '此物料组没有对应的物料!' TYPE 'E'. * EXIT. * ENDIF. IF ztlines <> ''. SPLIT ztlines AT '*' INTO ztlines1 ztlines2 ztlines3. ENDIF. LOOP AT t_zmal. SELECT SINGLE tlines INTO t_zmal-tlines FROM zmal WHERE matnr = t_zmal-matnr. * AND TLINES IN S_TLINES. * SELECT SINGLE EISBE BSTMI BSTFE * INTO (T_ZMAL-EISBE,T_ZMAL-BSTMI,T_ZMAL-BSTFE) * FROM MARC * WHERE MATNR = T_ZMAL-MATNR * AND WERKS = '7010'. * * SELECT SINGLE LABST * INTO T_ZMAL-LABST * FROM MARD * WHERE MATNR = T_ZMAL-MATNR * AND WERKS = '7010' * AND ( LGORT = 'WL61' OR LGORT = 'MT61' OR LGORT = 'EL61' OR LGORT ='WL65' OR LGORT = 'WL66'). MODIFY t_zmal. ENDLOOP. i1 = 0.i2 = 0.i3 = 0. IF ztlines <> ''. LOOP AT t_zmal. IF ztlines1 <> ''. SEARCH t_zmal-tlines FOR ztlines1. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDIF. IF ztlines2 <> ''. SEARCH t_zmal-tlines FOR ztlines2. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDIF. IF ztlines3 <> ''. SEARCH t_zmal-tlines FOR ztlines3. IF sy-subrc <> 0. DELETE t_zmal. ENDIF. ENDIF. ENDLOOP. ENDIF. CLEAR t_zmal1.REFRESH t_zmal1. *LOOP AT T_ZMAL. *SELECT MATNR BISMT *INTO CORRESPONDING FIELDS OF TABLE Z_MAL *FROM ZPM_YZ_MAL *WHERE MATNR = T_ZMAL-MATNR. *IF SY-SUBRC = 0. *LOOP AT Z_MAL. *MOVE T_ZMAL TO T_ZMAL1. *T_ZMAL1-BISMT = Z_MAL-BISMT. *APPEND T_ZMAL1. *ENDLOOP. *ELSE. *MOVE T_ZMAL TO T_ZMAL1. *APPEND T_ZMAL1. *ENDIF. *ENDLOOP. *CLEAR T_ZMAL.REFRESH T_ZMAL. *LOOP AT T_ZMAL1. *MOVE T_ZMAL1 TO T_ZMAL. *APPEND T_ZMAL. *ENDLOOP. * *IF ZKG <> ''. *SPLIT ZKW AT '*' INTO ZKG1 ZKG2 ZKG3. *ENDIF. *LOOP AT T_ZMAL. *IF ZKW1 <> ''. *SEARCH T_ZMAL-BISMT FOR ZKW1. * IF SY-SUBRC <> 0. * DELETE T_ZMAL. *ENDLOOP.* ENDIF. *ENDIF. *IF ZKW2 <> ''. *SEARCH T_ZMAL-BISMT FOR ZKW2. * IF SY-SUBRC <> 0. * DELETE T_ZMAL. * ENDIF. *ENDIF. *IF ZKW3 <> ''. *SEARCH T_ZMAL-BISMT FOR ZKW3. * IF SY-SUBRC <> 0. * DELETE T_ZMAL. * ENDIF. *ENDIF. LOOP AT t_zmal . * PERFORM GET_MD04_DATA USING T_ZMAL-MATNR T_ZMAL-WERKS. * MOVE-CORRESPONDING ITAB0 TO I_OUT. * LOOP AT MDEZX WHERE PLAAB = '02'. * EXCESS = EXCESS + MDEZX-MNG01. "可用库存 * IF MDEZX-DELB0 = 'STOCK' OR MDEZX-DELKZ = 'QM'. * STOCK = STOCK + MDEZX-MNG01. "STOCK * ENDIF. * IF MDEZX-PLUMI = '-'. "DEMAND * TOTAL_DEMAND = TOTAL_DEMAND + MDEZX-MNG01 * -1. * ELSE. * IF MDEZX-DELKZ = 'LA' "SHIPPING NOTIFICATION * OR MDEZX-DELKZ = 'LE' "NORMAL PO * OR MDEZX-DELKZ = 'BE'. "SA SCHEDULE LINE * OPEN_PO = OPEN_PO + MDEZX-MNG01. "OPEN PO * ENDIF. * ENDIF * PERFORM GET_MD04_DATA USING T_ZMAL-MATNR '7010'. * DATA:OPEN_PO LIKE MDEZ-MNG01. * LOOP AT MDEZX WHERE PLAAB = '02'. * IF MDEZX-DELKZ = 'BA' "NORMAL PO * OR MDEZX-DELKZ = 'BE'. "SA SCHEDULE LINE * OPEN_PO = OPEN_PO + MDEZX-MNG01. "OPEN PO * ENDIF. * ENDLOOP. * MOVE: OPEN_PO TO T_ZMAL-OPEN_PO . * CLEAR: OPEN_PO. SELECT SINGLE labst INTO t_zmal-open_po FROM mard WHERE matnr = t_zmal-matnr AND lgort = t_zmal-bismt AND werks = t_zmal-werks. MODIFY t_zmal. ENDLOOP. DATA:zbismt LIKE zpm_cs_mal_st-bismt. LOOP AT t_zmal . CLEAR:zbismt. *-----ECCUpgradeS4--------AB_ZACK--------20221028--------START * SELECT SINGLE bismt INTO zbismt FROM zpm_cs_mal_st WHERE matnr = t_zmal-matnr . SELECT bismt INTO zbismt FROM zpm_cs_mal_st UP TO 1 ROWS WHERE matnr = t_zmal-matnr ORDER BY PRIMARY KEY.ENDSELECT. *-----ECCUpgradeS4--------ABA_ZACK--------20221028--------END IF sy-subrc = 0 . t_zmal-bismt = zbismt. MODIFY t_zmal. ENDIF. ENDLOOP. PERFORM wlc_labst."2020.6.18 可用库存修改(去除预留) PERFORM wlc_eisbe."2021.3.25 安全库存筛选 REFRESH t_vbap. LOOP AT t_zmal . APPEND t_zmal TO t_vbap. ENDLOOP. * PERFORM FRM_WRITE_DATA. ENDFORM. " GET_DATA_GRID FORM frm_write_data. CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'MATNR' . gw_fieldcat-scrtext_l = '物料号' . gw_fieldcat-outputlen = 18. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'MEINS' . gw_fieldcat-scrtext_l = '单位' . gw_fieldcat-outputlen = 4. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'TLINES' . gw_fieldcat-scrtext_l = '字段长文本' . gw_fieldcat-outputlen = 50. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'LGORT' . gw_fieldcat-scrtext_l = '库位' . gw_fieldcat-outputlen = 5. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'BISMT' . gw_fieldcat-scrtext_l = '库格' . gw_fieldcat-outputlen = 10. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'MTART' . gw_fieldcat-scrtext_l = '物料类型' . gw_fieldcat-outputlen = 8. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'LABST' . gw_fieldcat-scrtext_l = '库存余量' . gw_fieldcat-outputlen = 8. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'BDMNG' . gw_fieldcat-scrtext_l = '预留数量' . gw_fieldcat-outputlen = 8. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'LABST1' . gw_fieldcat-scrtext_l = '实际可用库存' . gw_fieldcat-outputlen = 10. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'EISBE' . gw_fieldcat-scrtext_l = '安全库存' . gw_fieldcat-outputlen = 8. APPEND gw_fieldcat TO gt_fieldcat . * CLEAR GW_FIELDCAT . * GW_FIELDCAT-FIELDNAME = 'OPEN_PO' . * GW_FIELDCAT-SCRTEXT_L = '在途库存' . * GW_FIELDCAT-OUTPUTLEN = 8. * APPEND GW_FIELDCAT TO GT_FIELDCAT . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'BSTMI' . gw_fieldcat-scrtext_l = '最小采购量' . gw_fieldcat-outputlen = 10. APPEND gw_fieldcat TO gt_fieldcat . CLEAR gw_fieldcat . gw_fieldcat-fieldname = 'BSTFE' . gw_fieldcat-scrtext_l = '固定采购量' . gw_fieldcat-outputlen = 10. APPEND gw_fieldcat TO gt_fieldcat . * **定义列信息 *WA_ALV_FILED-COL_POS = 10. *WA_ALV_FILED-FIELDNAME = 'BSTFE'. " 对应的内表中的字段名称 *WA_ALV_FILED-SELTEXT_M = '固定采购量'. "ALV中显示的标题 *WA_ALV_FILED-OUTPUTLEN = 10. " 列的显示宽度,可以不设置 *APPEND WA_ALV_FILED TO WA_ALV_FILEDCAT. *CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' * EXPORTING * IT_FIELDCAT = WA_ALV_FILEDCAT * TABLES * T_OUTTAB = T_ZMAL. ENDFORM. FORM get_md04_data USING p_matnr p_werks. CLEAR: mdpsx,mdezx,mdsux. CLEAR: mdpsx[],mdezx[],mdsux[]. CALL FUNCTION 'MD_STOCK_REQUIREMENTS_LIST_API' EXPORTING matnr = p_matnr werks = p_werks TABLES mdpsx = mdpsx mdezx = mdezx mdsux = mdsux EXCEPTIONS material_plant_not_found = 1 plant_not_found = 2. ENDFORM. " GET_MD04_DATA *&---------------------------------------------------------------------* *& MODULE ZMATNR INPUT *&---------------------------------------------------------------------* * TEXT *----------------------------------------------------------------------* MODULE zmatnr INPUT. DATA: BEGIN OF i_mara OCCURS 0, *-----ECCUpgradeS4--------AB_ZACK--------20221027--------START * matnr type char22, matnr TYPE matnr, *-----ECCUpgradeS4--------AB_ZACK--------20221027--------END END OF i_mara. SELECT mara~matnr INTO CORRESPONDING FIELDS OF TABLE i_mara FROM marc INNER JOIN mara ON mara~matnr = marc~matnr WHERE marc~werks = '7010'. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = 'MATNR' dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = 'ZMATNR' value_org = 'S' TABLES value_tab = i_mara EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. ENDMODULE. " ZMATNR INPUT MODULE zkw INPUT. DATA: BEGIN OF i_zkw OCCURS 0, zkw TYPE char6, lgobe TYPE char16, END OF i_zkw. CLEAR i_zkw.REFRESH i_zkw. i_zkw-zkw = 'WL61'. APPEND i_zkw. i_zkw-zkw = 'MT61'. APPEND i_zkw. i_zkw-zkw = 'EL61'. APPEND i_zkw. i_zkw-zkw = 'WL65'. APPEND i_zkw. i_zkw-zkw = 'WL66'. APPEND i_zkw. LOOP AT i_zkw. SELECT SINGLE lgobe INTO i_zkw-lgobe FROM t001l WHERE werks = '7010' AND lgort = i_zkw-zkw. MODIFY i_zkw. ENDLOOP. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = 'ZKW' dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = 'ZKW' value_org = 'S' TABLES value_tab = i_zkw EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. ENDMODULE. " ZMATNR INPUT MODULE zkg INPUT. DATA: BEGIN OF i_zkg OCCURS 0, bismt TYPE char50, END OF i_zkg. DATA:zkw1(6). DATA: dynpfields TYPE TABLE OF dynpread WITH HEADER LINE. CLEAR: dynpfields, dynpfields[],zkw1.CLEAR i_zkg.REFRESH i_zkg. dynpfields-fieldname = 'ZKW'. "填入需要读值的字段名 APPEND dynpfields. CALL FUNCTION 'DYNP_VALUES_READ' EXPORTING dyname = sy-repid dynumb = sy-dynnr translate_to_upper = 'X' TABLES dynpfields = dynpfields EXCEPTIONS OTHERS = 9. IF sy-subrc = 0. READ TABLE dynpfields WITH KEY fieldname = 'ZKW'. zkw1 = dynpfields-fieldvalue. "备注 ENDIF. IF zkw1 <> ''. SELECT bismt INTO CORRESPONDING FIELDS OF TABLE i_zkg FROM zpm_yz_mal_st WHERE werks = '7010' AND lgort = zkw1. ELSE. SELECT bismt INTO CORRESPONDING FIELDS OF TABLE i_zkg FROM zpm_yz_mal_st WHERE werks = '7010'. ENDIF. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = 'BISMT' dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = 'ZKG' value_org = 'S' TABLES value_tab = i_zkg EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. ENDMODULE. " ZMATNR INPUT *&---------------------------------------------------------------------* *& Form WLC_LABST *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM wlc_labst . DATA:bdmng LIKE resb-bdmng, enmng LIKE resb-enmng. DATA:shkzg LIKE resb-shkzg. LOOP AT t_zmal. SELECT bdmng enmng shkzg INTO ( bdmng,enmng,shkzg ) FROM resb WHERE xloek = '' AND kzear = '' AND matnr = t_zmal-matnr AND werks = t_zmal-werks AND lgort = t_zmal-lgort. IF shkzg = 'H'. t_zmal-bdmng = t_zmal-bdmng + bdmng - enmng. ELSE. t_zmal-bdmng = t_zmal-bdmng - bdmng + enmng. ENDIF. CLEAR:bdmng,enmng,shkzg. ENDSELECT. t_zmal-labst1 = t_zmal-labst - t_zmal-bdmng. MODIFY t_zmal. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form WLC_EISBE *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM wlc_eisbe . IF fxk01 <> ''. LOOP AT t_zmal. IF t_zmal-labst1 >= t_zmal-eisbe. DELETE t_zmal. ENDIF. ENDLOOP. ENDIF. ENDFORM.
08-09
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; namespace ScaffoldPlugin { public class ScaffoldGenerator { // 图块尺寸映射 private static readonly Dictionary<string, int> BlockSizes = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase) { // 立杆 {"ScaffoldPole立杆200mm", 200}, {"ScaffoldPole立杆350mm", 350}, {"ScaffoldPole立杆500mm", 500}, {"ScaffoldPole立杆1000mm", 1000}, {"ScaffoldPole立杆1500mm", 1500}, {"ScaffoldPole立杆2000mm", 2000}, {"ScaffoldPole立杆2500mm", 2500}, // 横杆 {"ScaffoldPole立横杆300mm", 300}, {"ScaffoldPole立横杆600mm", 600}, {"ScaffoldPole立横杆900mm", 900}, {"ScaffoldPole立横杆1200mm", 1200}, {"ScaffoldPole立横杆1500mm", 1500}, {"ScaffoldPole立横杆1800mm", 1800}, // 附件 {"ScaffoldPole顶托", 0}, {"ScaffoldPole顶托螺母", 0}, {"ScaffoldPole连接盘", 0}, // 竖向斜拉杆 {"ScaffoldPolexie竖向斜拉杆600mm", 600}, {"ScaffoldPolexie竖向斜拉杆900mm", 900}, {"ScaffoldPolexie竖向斜拉杆1500mm", 1500}, {"ScaffoldPolexie竖向斜拉杆1800mm", 1800}, // 水平斜拉杆 {"ScaffoldPolehengxie水平斜拉杆", 0} }; // 斜拉杆尺寸到图块名称的映射 private static readonly Dictionary<int, string> XieBarBlockMap = new Dictionary<int, string> { {600, "ScaffoldPolexie竖向斜拉杆600mm"}, {900, "ScaffoldPolexie竖向斜拉杆900mm"}, {1500, "ScaffoldPolexie竖向斜拉杆1500mm"}, {1800, "ScaffoldPolexie竖向斜拉杆1800mm"} }; // 顶部横杆偏移映射 private static readonly Dictionary<int, double> TopBarOffsets = new Dictionary<int, double> { {200, 105}, {350, 125}, {500, 250}, {1000, 750}, {1500, 1250}, {2000, 1750}, {2500, 2250} }; // 常量定义 private const double FirstBarHeight = 250.0; private const double HorizontalBarSpacing = 1500.0; private const double StandardDiskOffset = 250.0; private const double Tolerance = 5.0; private const double NutOffset = 75.0; private const double MinTopGap = 200.0; private const double MaxTopGap = 400.0; private const double RelaxedTolerance = 50.0; private const double MaxBarDistance = 1800.0; private const double MaxDiskSearchDistance = 500.0; private const double HeightDifferenceThreshold = 50.0; private const double TopControlLineTolerance = 10.0; private const double DimensionOffset = 600.0; private const double XieBarSpacing = 1.0; // 每步都布置斜拉杆 private const double MinXieBarStep = 1500.0; // 斜拉杆最小步距 private Editor _ed; private string _blocksFolderPath; private Curve _topControlLine; private bool _isAscending; private readonly Dictionary<double, List<double>> _diskPositions = new Dictionary<double, List<double>>(); private readonly Dictionary<double, double> _adjusterPositions = new Dictionary<double, double>(); private readonly Dictionary<double, int> _lastPoleSizes = new Dictionary<double, int>(); private readonly Dictionary<double, double> _poleBasePositions = new Dictionary<double, double>(); private readonly Dictionary<double, double> _topDiskPositions = new Dictionary<double, double>(); private readonly HashSet<Tuple<double, double>> _placedHorizontalBars = new HashSet<Tuple<double, double>>(); private readonly List<Tuple<double, double, double>> _horizontalXieBarPositions = new List<Tuple<double, double, double>>(); // 记录所有插入的斜拉杆图块ID private readonly List<ObjectId> _insertedXieBars = new List<ObjectId>(); // 记录所有插入的横杆图块ID private readonly List<ObjectId> _insertedHorizontalBars = new List<ObjectId>(); [CommandMethod("GS", CommandFlags.Modal)] public void GenerateScaffold() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; _ed = doc.Editor; try { _ed.WriteMessage("\n脚手架生成开始..."); _blocksFolderPath = GetBlocksFolderPath(); if (string.IsNullOrEmpty(_blocksFolderPath)) { _ed.WriteMessage("\n错误:无法获取图块文件夹路径"); return; } LoadAllBlockDefinitions(db); var blockRefs = SelectBlocks(); if (blockRefs == null || blockRefs.Count == 0) { _ed.WriteMessage("\n未选择任何脚手架图块"); return; } _ed.WriteMessage($"\n已选择 {blockRefs.Count} 个脚手架图块"); _ed.WriteMessage("\n选择底标高水平控制线"); var baseLine = SelectControlLine(); if (baseLine == null) { _ed.WriteMessage("\n未选择底标高水平控制线"); return; } double baseElev = GetLineElevation(baseLine); _ed.WriteMessage($"\n底标高: {baseElev}"); _ed.WriteMessage("\n选择顶部控制线"); _topControlLine = SelectControlLine(); if (_topControlLine == null) { _ed.WriteMessage("\n未选择顶部控制线"); return; } double topElev = GetLineElevation(_topControlLine); _ed.WriteMessage($"\n顶标高: {topElev}"); using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); // 重置所有数据结构 ResetDataStructures(); // 收集水平斜拉杆位置 CollectHorizontalXieBarPositions(blockRefs); // 布置立杆 LayoutVerticalPoles(tr, bt, btr, blockRefs, baseElev); // 布置横杆 LayoutHorizontalBars(tr, bt, btr, blockRefs, baseElev); // 布置斜拉杆 LayoutXieBars(tr, bt, btr, baseElev); // 删除无效的横杆(两侧无连接盘) RemoveInvalidHorizontalBars(tr, btr); // 删除步距过小的斜拉杆 RemoveSmallStepXieBars(tr, btr); // 添加尺寸标注 AddDimensions(tr, btr, db, baseElev); tr.Commit(); } _ed.WriteMessage("\n脚手架生成完成!"); } catch (Autodesk.AutoCAD.Runtime.Exception acadEx) { if (acadEx.ErrorStatus != ErrorStatus.UserBreak) { _ed.WriteMessage($"\nAutoCAD错误: {acadEx.Message}"); _ed.WriteMessage($"\n堆栈跟踪: {acadEx.StackTrace}"); } } catch (System.Exception sysEx) { _ed.WriteMessage($"\n系统错误: {sysEx.Message}"); _ed.WriteMessage($"\n堆栈跟踪: {sysEx.StackTrace}"); } } // 重置数据结构 private void ResetDataStructures() { _diskPositions.Clear(); _adjusterPositions.Clear(); _lastPoleSizes.Clear(); _poleBasePositions.Clear(); _topDiskPositions.Clear(); _placedHorizontalBars.Clear(); _horizontalXieBarPositions.Clear(); _insertedXieBars.Clear(); _insertedHorizontalBars.Clear(); } private void CollectHorizontalXieBarPositions(List<BlockReference> blocks) { try { // 收集所有水平斜拉杆位置 var xieBarBlocks = blocks .Where(b => b.Name.Contains("hengxie") || b.Name.Contains("水平斜拉杆")) .ToList(); foreach (var block in xieBarBlocks) { // 获取块的几何范围 Extents3d extents = block.GeometricExtents; // 计算起点和终点 double startX = extents.MinPoint.X; double endX = extents.MaxPoint.X; double height = block.Position.Y; _horizontalXieBarPositions.Add(new Tuple<double, double, double>(startX, endX, height)); } _ed.WriteMessage($"\n找到 {xieBarBlocks.Count} 个水平斜拉杆位置"); } catch (System.Exception ex) { _ed.WriteMessage($"\n收集水平斜拉杆位置错误: {ex.Message}"); } } private void LayoutXieBars(Transaction tr, BlockTable bt, BlockTableRecord btr, double baseElev) { try { _ed.WriteMessage("\n开始布置竖向斜拉杆..."); int xieBarCount = 0; int skippedCount = 0; // 获取所有立杆位置(按X排序) var polePositions = _poleBasePositions.Keys.OrderBy(x => x).ToList(); if (polePositions.Count < 2) { _ed.WriteMessage("\n立杆数量不足,无法布置斜拉杆"); return; } // 计算最大高度(考虑安全距离) double maxHeight = _isAscending ? _topDiskPositions.Values.Max() - MinTopGap : _topDiskPositions.Values.Min() + MinTopGap; // 遍历每个水平斜拉杆位置 foreach (var xieBarPos in _horizontalXieBarPositions) { double startX = xieBarPos.Item1; double endX = xieBarPos.Item2; double barHeight = xieBarPos.Item3; _ed.WriteMessage($"\n处理水平斜拉杆: {startX:F0} - {endX:F0} 高度 {barHeight:F0}"); // 找到最近的立杆位置 double? leftPole = FindNearestPole(startX, polePositions); double? rightPole = FindNearestPole(endX, polePositions); if (!leftPole.HasValue || !rightPole.HasValue) { _ed.WriteMessage($"\n 找不到对应的立杆位置"); continue; } // 获取左右立杆之间的所有立杆 var polesInRange = polePositions .Where(x => x >= leftPole.Value && x <= rightPole.Value) .OrderBy(x => x) .ToList(); if (polesInRange.Count < 2) { _ed.WriteMessage($"\n 跨间内立杆不足"); continue; } // 计算步距高度列表(从水平斜拉杆高度开始向上布置) var stepHeights = new List<double>(); double currentHeight = barHeight; double stepDirection = _isAscending ? 1 : -1; // 计算最大步数(避免超出最大高度) while ((_isAscending && currentHeight <= maxHeight) || (!_isAscending && currentHeight >= maxHeight)) { // 添加当前高度 stepHeights.Add(currentHeight); // 计算下一高度 currentHeight += HorizontalBarSpacing * stepDirection; // 检查是否超出范围(使用安全高度) if ((_isAscending && currentHeight > maxHeight) || (!_isAscending && currentHeight < maxHeight)) { break; } } _ed.WriteMessage($"\n 计算得到 {stepHeights.Count} 个布置高度"); // 遍历每个跨间(相邻立杆之间) for (int i = 0; i < polesInRange.Count - 1; i++) { double leftX = polesInRange[i]; double rightX = polesInRange[i + 1]; double distance = Math.Abs(rightX - leftX); // 跳过过远或过近的跨间 if (distance < 300 || distance > MaxBarDistance) { _ed.WriteMessage($"\n 跳过跨间 {i} (距离 {distance} 不在范围内)"); continue; } // 在每个步距高度上布置斜拉杆 foreach (double height in stepHeights) { // 获取左右立杆上最接近的连接盘高度 double? leftDisk = GetNearestDiskHeight(leftX, height, 100.0); // 使用更大的容差 double? rightDisk = GetNearestDiskHeight(rightX, height, 100.0); if (!leftDisk.HasValue || !rightDisk.HasValue) { _ed.WriteMessage($"\n 在高度 {height:F0} 找不到连接盘"); skippedCount++; continue; } // 计算实际安装高度(取平均值) double actualHeight = (leftDisk.Value + rightDisk.Value) / 2.0; // 增强高度验证 if (Math.Abs(actualHeight) < 1.0 || double.IsNaN(actualHeight) || double.IsInfinity(actualHeight)) { _ed.WriteMessage($"\n 无效高度: {actualHeight:F0} (左={leftDisk.Value}, 右={rightDisk.Value})"); skippedCount++; continue; } // 使用中点位置的控制线高度进行安全距离检查 double midX = (leftX + rightX) / 2.0; double controlY = GetElevationAtX(midX); // 检查是否超出顶部控制线 bool isOverTop = _isAscending ? (actualHeight > controlY - MinTopGap) : (actualHeight < controlY + MinTopGap); if (isOverTop) { _ed.WriteMessage($"\n 超出顶控制线: {actualHeight:F0} vs {controlY - MinTopGap:F0} - 已跳过"); skippedCount++; continue; } // 计算实际需要的斜拉杆长度 double actualDistance = Math.Sqrt( Math.Pow(rightX - leftX, 2) + Math.Pow(0, 2) // 高度相同,所以高度差为0 ); // 选择最佳斜拉杆尺寸 int bestSize = GetBestXieBarSize(actualDistance); if (bestSize <= 0) { _ed.WriteMessage($"\n 找不到合适的斜拉杆尺寸: {actualDistance}"); skippedCount++; continue; } // 获取图块名称 if (!XieBarBlockMap.TryGetValue(bestSize, out string blockName) || !bt.Has(blockName)) { _ed.WriteMessage($"\n 找不到图块: {bestSize}mm"); skippedCount++; continue; } // 计算中点 double midY = actualHeight; // 计算旋转角度(水平方向) double dx = rightX - leftX; double dy = 0; // 同一高度,高度差为0 double angle = Math.Atan2(dy, dx); // 结果为0,水平方向 // 八字形布置:基于跨间位置决定方向 bool isPositiveSlope = (Math.Floor(midX / 3000) % 2 == 0); // 每3米交替方向 // 创建镜像矩阵 Matrix3d mirrorMatrix = isPositiveSlope ? Matrix3d.Identity : Matrix3d.Mirroring(new Line3d( new Point3d(midX, midY, 0), new Point3d(midX, midY + 1, 0) )); // 插入斜拉杆 InsertXieBarBlock(tr, btr, bt, blockName, midX, midY, angle, mirrorMatrix); xieBarCount++; _ed.WriteMessage($"\n 在高度 {actualHeight:F0} 处布置斜拉杆"); } } } _ed.WriteMessage($"\n共布置 {xieBarCount} 根竖向斜拉杆"); _ed.WriteMessage($"\n跳过 {skippedCount} 个无效位置"); } catch (System.Exception ex) { _ed.WriteMessage($"\n布置斜拉杆错误: {ex.Message}"); } } // 删除步距过小的斜拉杆 private void RemoveSmallStepXieBars(Transaction tr, BlockTableRecord btr) { try { int removedCount = 0; var barsToRemove = new List<ObjectId>(); // 按高度分组排序 var barsByPosition = _insertedXieBars .Where(id => id.IsValid && !id.IsErased) .Select(id => new { Id = id, Position = (tr.GetObject(id, OpenMode.ForRead) as BlockReference}) .Where(item => item.Position != null) .GroupBy(item => item.Position.Position.X) .ToList(); foreach (var group in barsByPosition) { // 按Y坐标排序 var sortedBars = group .Select(item => item.Position) .OrderBy(bref => _isAscending ? bref.Position.Y : -bref.Position.Y) .ToList(); // 检查相邻斜拉杆的步距 for (int i = 0; i < sortedBars.Count - 1; i++) { double height1 = sortedBars[i].Position.Y; double height2 = sortedBars[i + 1].Position.Y; double step = Math.Abs(height2 - height1); if (step < MinXieBarStep - Tolerance) { barsToRemove.Add(sortedBars[i].ObjectId); barsToRemove.Add(sortedBars[i + 1].ObjectId); removedCount += 2; i++; // 跳过下一个 } } } // 删除步距过小的斜拉杆 foreach (ObjectId id in barsToRemove) { BlockReference bref = tr.GetObject(id, OpenMode.ForWrite) as BlockReference; if (bref != null) { bref.Erase(); } } _ed.WriteMessage($"\n删除 {removedCount} 根步距小于{MinXieBarStep}mm的斜拉杆"); } catch (System.Exception ex) { _ed.WriteMessage($"\n删除步距过小斜拉杆错误: {ex.Message}"); } } // 删除无效的横杆(两侧无连接盘) private void RemoveInvalidHorizontalBars(Transaction tr, BlockTableRecord btr) { try { int removedCount = 0; var barsToRemove = new List<ObjectId>(); foreach (ObjectId id in _insertedHorizontalBars) { if (!id.IsValid || id.IsErased) continue; BlockReference bref = tr.GetObject(id, OpenMode.ForRead) as BlockReference; if (bref == null) continue; // 横杆中点坐标 double midX = bref.Position.X; double midY = bref.Position.Y; // 查找最近的左右立杆 var leftPole = _poleBasePositions.Keys .Where(x => x < midX) .OrderByDescending(x => x) .FirstOrDefault(); var rightPole = _poleBasePositions.Keys .Where(x => x > midX) .OrderBy(x => x) .FirstOrDefault(); if (leftPole == 0 || rightPole == 0) { // 找不到立杆,删除 barsToRemove.Add(id); removedCount++; continue; } // 检查两侧是否有连接盘 bool hasLeftDisk = HasDiskAtHeight(leftPole, midY, Tolerance); bool hasRightDisk = HasDiskAtHeight(rightPole, midY, Tolerance); if (!hasLeftDisk || !hasRightDisk) { barsToRemove.Add(id); removedCount++; } } // 删除无效横杆 foreach (ObjectId id in barsToRemove) { BlockReference bref = tr.GetObject(id, OpenMode.ForWrite) as BlockReference; if (bref != null) { bref.Erase(); } } _ed.WriteMessage($"\n删除 {removedCount} 根两侧无连接盘的横杆"); } catch (System.Exception ex) { _ed.WriteMessage($"\n删除无效横杆错误: {ex.Message}"); } } // 改进的斜拉杆尺寸选择方法 private int GetBestXieBarSize(double distance) { if (distance <= 0) return 0; // 精确匹配优先(容差±5%) int[] validSizes = { 600, 900, 1500, 1800 }; var exactMatch = validSizes .Where(s => Math.Abs(s - distance) <= distance * 0.05) .OrderBy(s => Math.Abs(s - distance)) .FirstOrDefault(); if (exactMatch > 0) return exactMatch; // 宽松匹配(容差±15%) return validSizes .Where(s => Math.Abs(s - distance) <= distance * 0.15) .OrderBy(s => Math.Abs(s - distance)) .FirstOrDefault(); } // 增强的高度获取方法 private double GetElevationAtX(double x) { if (_topControlLine == null) return 0; try { // 增加对多段线的精确处理 if (_topControlLine is Polyline pline) { for (int i = 0; i < pline.NumberOfVertices - 1; i++) { Point3d start = pline.GetPoint3dAt(i); Point3d end = pline.GetPoint3dAt(i + 1); if (x >= Math.Min(start.X, end.X) && x <= Math.Max(start.X, end.X)) { double t = (x - start.X) / (end.X - start.X); return start.Y + t * (end.Y - start.Y); } } return pline.GetPoint3dAt(0).Y; } // 直线处理 if (_topControlLine is Line line) { Vector3d direction = line.EndPoint - line.StartPoint; if (Math.Abs(direction.X) < 0.001) return line.StartPoint.Y; double t = (x - line.StartPoint.X) / direction.X; return line.StartPoint.Y + t * direction.Y; } return 0; } catch { return 0; } } private string GetBlocksFolderPath() { try { string assemblyPath = Assembly.GetExecutingAssembly().Location; string pluginDir = Path.GetDirectoryName(assemblyPath); return Path.Combine(pluginDir, "ScaffoldBlocks"); } catch (System.Exception ex) { _ed.WriteMessage($"\n获取图块路径错误: {ex.Message}"); return null; } } private void LoadAllBlockDefinitions(Database db) { if (string.IsNullOrEmpty(_blocksFolderPath)) return; try { string[] blockFiles = Directory.GetFiles(_blocksFolderPath, "*.dwg"); if (blockFiles.Length == 0) { _ed.WriteMessage("\n未找到任何图块文件"); return; } using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); foreach (string filePath in blockFiles) { string fileName = Path.GetFileNameWithoutExtension(filePath); if (!BlockSizes.ContainsKey(fileName)) continue; if (bt.Has(fileName)) continue; using (Database sourceDb = new Database(false, true)) { try { sourceDb.ReadDwgFile(filePath, FileShare.Read, true, null); ObjectId blockId = db.Insert(fileName, sourceDb, true); _ed.WriteMessage($"\n已加载图块: {fileName}"); } catch (System.Exception ex) { _ed.WriteMessage($"\n加载图块 {fileName} 失败: {ex.Message}"); } } } tr.Commit(); } } catch (System.Exception ex) { _ed.WriteMessage($"\n加载图块定义错误: {ex.Message}"); } } private Curve SelectControlLine() { try { var opts = new PromptEntityOptions("\n选择控制线: ") { AllowNone = false, AllowObjectOnLockedLayer = true }; opts.SetRejectMessage("\n必须选择直线或多段线"); opts.AddAllowedClass(typeof(Line), true); opts.AddAllowedClass(typeof(Polyline), true); PromptEntityResult result = _ed.GetEntity(opts); if (result.Status != PromptStatus.OK) return null; using (Transaction tr = _ed.Document.TransactionManager.StartTransaction()) { Curve curve = tr.GetObject(result.ObjectId, OpenMode.ForRead) as Curve; tr.Commit(); return curve; } } catch (System.Exception ex) { _ed.WriteMessage($"\n选择控制线错误: {ex.Message}"); return null; } } private double GetLineElevation(Curve curve) { if (curve == null) return 0; try { if (curve is Line line) return line.StartPoint.Y; if (curve is Polyline pline) return pline.GetPoint3dAt(0).Y; return 0; } catch (System.Exception ex) { _ed.WriteMessage($"\n获取控制线高程错误: {ex.Message}"); return 0; } } private List<BlockReference> SelectBlocks() { try { var filter = new SelectionFilter(new[] { new TypedValue(0, "INSERT"), new TypedValue(2, "ScaffoldPole*") }); var selOptions = new PromptSelectionOptions { MessageForAdding = "\n框选脚手架图块: ", AllowDuplicates = false }; PromptSelectionResult selResult = _ed.GetSelection(selOptions, filter); if (selResult.Status != PromptStatus.OK) return null; var references = new List<BlockReference>(); using (var resBuf = selResult.Value) { Database db = _ed.Document.Database; using (Transaction tr = db.TransactionManager.StartTransaction()) { foreach (ObjectId objId in resBuf.GetObjectIds()) { var bref = tr.GetObject(objId, OpenMode.ForRead) as BlockReference; if (bref != null) references.Add(bref); } tr.Commit(); } } return references; } catch (System.Exception ex) { _ed.WriteMessage($"\n选择图块错误: {ex.Message}"); return null; } } private void LayoutVerticalPoles( Transaction tr, BlockTable bt, BlockTableRecord btr, List<BlockReference> blocks, double baseElev) { try { _ed.WriteMessage("\n开始布置立杆..."); var polePositions = blocks .Where(b => b.Name.Contains("立杆") && !b.Name.Contains("横杆")) .Select(b => b.Position.X) .Distinct() .OrderBy(x => x) .ToList(); if (polePositions.Count == 0) { _ed.WriteMessage("\n未找到立杆位置"); return; } double minY = polePositions.Min(x => GetElevationAtX(x)); double maxY = polePositions.Max(x => GetElevationAtX(x)); _isAscending = maxY > minY; int[] standardSizes = { 2500, 2000, 1500, 1000, 500, 350, 200 }; foreach (var xPos in polePositions) { _poleBasePositions[xPos] = baseElev; double topElev = GetElevationAtX(xPos); double totalHeight = Math.Abs(topElev - baseElev); double currentY = baseElev; List<int> usedSizes = new List<int>(); double remaining = totalHeight; while (remaining > MinTopGap + 350) { double maxUsableSize = remaining - MinTopGap; int bestSize = standardSizes .Where(s => s <= maxUsableSize) .OrderByDescending(s => s) .FirstOrDefault(); if (bestSize <= 0) break; usedSizes.Add(bestSize); remaining -= bestSize; currentY += _isAscending ? bestSize : -bestSize; } int lastPoleSize = 0; double gap = 0; double minGap = MinTopGap; double maxGap = MaxTopGap; var validLastSizes = standardSizes .Where(s => s <= remaining - minGap && s >= remaining - maxGap) .OrderByDescending(s => s) .ToList(); if (validLastSizes.Any()) { lastPoleSize = validLastSizes.First(); gap = remaining - lastPoleSize; } else { lastPoleSize = standardSizes .OrderBy(s => Math.Abs((remaining - s) - 300)) .First(); gap = remaining - lastPoleSize; if (gap < minGap && usedSizes.Count > 0) { int lastStandard = usedSizes.Last(); usedSizes.RemoveAt(usedSizes.Count - 1); remaining += lastStandard; currentY += _isAscending ? -lastStandard : lastStandard; lastPoleSize = standardSizes .Where(s => s <= remaining - minGap) .OrderByDescending(s => s) .First(); gap = remaining - lastPoleSize; } } usedSizes.Add(lastPoleSize); gap = remaining - lastPoleSize; _lastPoleSizes[xPos] = lastPoleSize; currentY = baseElev; foreach (int size in usedSizes) { string blockName = $"ScaffoldPole立杆{size}mm"; if (bt.Has(blockName)) { InsertBlock(tr, btr, bt, blockName, xPos, currentY); RecordDiskPositions(xPos, currentY, size); currentY += _isAscending ? size : -size; } else { _ed.WriteMessage($"\n找不到图块: {blockName}"); } } if (bt.Has("ScaffoldPole顶托")) { double topPosition = topElev; InsertBlock(tr, btr, bt, "ScaffoldPole顶托", xPos, topPosition); _adjusterPositions[xPos] = topPosition; // 添加顶部横杆位置计算 if (TopBarOffsets.TryGetValue(lastPoleSize, out double topBarOffset)) { double topBarY = _isAscending ? topPosition - topBarOffset : topPosition + topBarOffset; // 记录顶部横杆位置 if (!_diskPositions.ContainsKey(xPos)) _diskPositions[xPos] = new List<double>(); if (!_diskPositions[xPos].Contains(topBarY)) _diskPositions[xPos].Add(topBarY); _ed.WriteMessage($"\n记录顶部横杆位置: X={xPos}, 高度={topBarY:F1}"); } double nutPosition = _isAscending ? (currentY + NutOffset) : (currentY - NutOffset); if (bt.Has("ScaffoldPole顶托螺母")) { InsertBlock(tr, btr, bt, "ScaffoldPole顶托螺母", xPos, nutPosition); } } } _ed.WriteMessage($"\n布置了 {polePositions.Count} 根立杆"); } catch (System.Exception ex) { _ed.WriteMessage($"\n布置立杆错误: {ex.Message}"); } } private void RecordDiskPositions(double x, double startY, int poleSize) { try { if (!_diskPositions.ContainsKey(x)) _diskPositions[x] = new List<double>(); double actualTopY = GetElevationAtX(x); double direction = _isAscending ? 1 : -1; // 添加第一个连接盘位置(250mm处) double firstDiskY = startY + FirstBarHeight * direction; if (!_diskPositions[x].Contains(firstDiskY)) _diskPositions[x].Add(firstDiskY); int stepCount = 1; while (true) { double diskHeight = FirstBarHeight + stepCount * HorizontalBarSpacing; double diskY = startY + diskHeight * direction; // 检查是否超过顶部控制线 if ((_isAscending && diskY > actualTopY - MinTopGap) || (!_isAscending && diskY < actualTopY + MinTopGap)) { break; } if (!_diskPositions[x].Contains(diskY)) _diskPositions[x].Add(diskY); stepCount++; } // 添加顶部控制线位置 if (!_diskPositions[x].Contains(actualTopY)) _diskPositions[x].Add(actualTopY); _topDiskPositions[x] = actualTopY; // 调试日志 _ed.WriteMessage($"\n立杆位置: X={x}, 底部={startY}, 顶部={actualTopY}"); _ed.WriteMessage($"\n连接盘位置: {string.Join(", ", _diskPositions[x])}"); } catch (System.Exception ex) { _ed.WriteMessage($"\n记录连接盘位置错误: {ex.Message}"); } } private void LayoutHorizontalBars( Transaction tr, BlockTable bt, BlockTableRecord btr, List<BlockReference> blocks, double baseElev) { try { _ed.WriteMessage("\n开始布置横杆..."); var poleXPositions = _poleBasePositions.Keys .OrderBy(x => x) .ToList(); if (poleXPositions.Count < 2) { _ed.WriteMessage("\n立杆不足,无法布置横杆"); return; } // 布置常规横杆(从底部250mm开始,步距1500mm) PlaceRegularHorizontalBars(tr, bt, btr, poleXPositions, baseElev); // 布置顶部横杆(根据立杆尺寸的特殊位置) PlaceTopBarsOnDisks(tr, bt, btr, poleXPositions); _ed.WriteMessage($"\n布置了 {_placedHorizontalBars.Count} 根横杆"); } catch (System.Exception ex) { _ed.WriteMessage($"\n布置横杆错误: {ex.Message}"); } } private void PlaceRegularHorizontalBars( Transaction tr, BlockTable bt, BlockTableRecord btr, List<double> poleXPositions, double baseElev) { try { _ed.WriteMessage("\n开始布置常规横杆..."); int regularBarCount = 0; // 计算所有可能的横杆高度 List<double> barHeights = CalculateBarHeights(poleXPositions, baseElev); _ed.WriteMessage($"\n计算得到 {barHeights.Count} 个横杆高度"); // 按高度布置横杆 foreach (double originalHeight in barHeights) { double currentHeight = originalHeight; // 创建可修改的副本 for (int i = 0; i < poleXPositions.Count - 1; i++) { double x1 = poleXPositions[i]; double x2 = poleXPositions[i + 1]; double distance = Math.Abs(x2 - x1); // 跳过距离过大的立杆对 if (distance > MaxBarDistance) continue; // 检查两侧是否有连接盘 bool hasDisk1 = HasDiskAtHeight(x1, currentHeight, Tolerance); bool hasDisk2 = HasDiskAtHeight(x2, currentHeight, Tolerance); double actualHeight = currentHeight; // 实际安装高度 bool heightAdjusted = false; // 标记高度是否被调整 // 如果一侧没有连接盘,尝试在附近寻找替代位置 if (!hasDisk1 || !hasDisk2) { // 尝试在下方寻找最近的连接盘 double? altHeight1 = hasDisk1 ? currentHeight : FindNearestDiskBelow(x1, currentHeight, MaxDiskSearchDistance); double? altHeight2 = hasDisk2 ? currentHeight : FindNearestDiskBelow(x2, currentHeight, MaxDiskSearchDistance); // 检查替代高度是否有效且一致 if (altHeight1.HasValue && altHeight2.HasValue && Math.Abs(altHeight1.Value - altHeight2.Value) <= HeightDifferenceThreshold) { actualHeight = (altHeight1.Value + altHeight2.Value) / 2.0; heightAdjusted = true; } else { continue; // 跳过这个位置 } } // 检查是否已布置过相同位置的横杆 double midX = (x1 + x2) / 2.0; if (_placedHorizontalBars.Any(p => Math.Abs(p.Item1 - midX) < Tolerance && Math.Abs(p.Item2 - actualHeight) < Tolerance)) { continue; } // 选择最佳横杆尺寸 int bestSize = GetBestBarSize(distance); if (bestSize <= 0) continue; string blockName = $"ScaffoldPole立横杆{bestSize}mm"; if (!bt.Has(blockName)) continue; // 插入横杆 InsertHorizontalBarBlock(tr, btr, bt, blockName, midX, actualHeight); regularBarCount++; // 记录已布置的横杆位置 _placedHorizontalBars.Add(new Tuple<double, double>(midX, actualHeight)); if (heightAdjusted) { _ed.WriteMessage($"\n在调整高度 {actualHeight:F0} 处布置横杆 (原计划高度: {currentHeight:F0})"); } } } _ed.WriteMessage($"\n布置了 {regularBarCount} 根常规横杆"); } catch (System.Exception ex) { _ed.WriteMessage($"\n布置常规横杆错误: {ex.Message}"); } } private void PlaceTopBarsOnDisks( Transaction tr, BlockTable bt, BlockTableRecord btr, List<double> poleXPositions) { try { _ed.WriteMessage("\n开始布置顶部横杆..."); int topBarCount = 0; for (int i = 0; i < poleXPositions.Count - 1; i++) { double x1 = poleXPositions[i]; double x2 = poleXPositions[i + 1]; double distance = Math.Abs(x2 - x1); if (distance > MaxBarDistance) continue; // 获取顶部立杆尺寸 if (!_lastPoleSizes.TryGetValue(x1, out int lastSize1) || !_lastPoleSizes.TryGetValue(x2, out int lastSize2)) { continue; } // 获取顶托位置 if (!_adjusterPositions.TryGetValue(x1, out double topPos1) || !_adjusterPositions.TryGetValue(x2, out double topPos2)) { continue; } // 计算顶部横杆位置 double topBarY1 = _isAscending ? topPos1 - TopBarOffsets[lastSize1] : topPos1 + TopBarOffsets[lastSize1]; double topBarY2 = _isAscending ? topPos2 - TopBarOffsets[lastSize2] : topPos2 + TopBarOffsets[lastSize2]; // 检查高度差是否在允许范围内 double heightDiff = Math.Abs(topBarY1 - topBarY2); if (heightDiff > HeightDifferenceThreshold) continue; double barHeight = (topBarY1 + topBarY2) / 2.0; // 检查是否已布置 double midX = (x1 + x2) / 2.0; if (_placedHorizontalBars.Any(p => Math.Abs(p.Item1 - midX) < Tolerance && Math.Abs(p.Item2 - barHeight) < Tolerance)) { continue; } // 检查两侧是否有连接盘 bool hasDisk1 = HasDiskAtHeight(x1, barHeight, Tolerance); bool hasDisk2 = HasDiskAtHeight(x2, barHeight, Tolerance); if (!hasDisk1 || !hasDisk2) { _ed.WriteMessage($"\n跳过顶部横杆,在高度{barHeight:F0}缺少连接盘: x1={x1}, x2={x2}"); continue; } // 使用"立横杆"图块名称 int bestSize = GetBestBarSize(distance); if (bestSize <= 0) continue; string blockName = $"ScaffoldPole立横杆{bestSize}mm"; if (!bt.Has(blockName)) continue; InsertHorizontalBarBlock(tr, btr, bt, blockName, midX, barHeight); topBarCount++; // 记录已布置的横杆位置 _placedHorizontalBars.Add(new Tuple<double, double>(midX, barHeight)); _ed.WriteMessage($"\n在高度 {barHeight:F1} 布置顶部横杆 (尺寸={bestSize}mm, 偏移量={TopBarOffsets[lastSize1]}/{TopBarOffsets[lastSize2]}mm)"); } _ed.WriteMessage($"\n布置了 {topBarCount} 根顶部横杆"); } catch (System.Exception ex) { _ed.WriteMessage($"\n布置顶部横杆错误: {ex.Message}"); } } private List<double> CalculateBarHeights(List<double> polePositions, double baseElev) { var barHeights = new List<double>(); try { double firstBarHeight = _isAscending ? baseElev + FirstBarHeight : baseElev - FirstBarHeight; barHeights.Add(firstBarHeight); double maxHeight = _isAscending ? _topDiskPositions.Values.Max() : _topDiskPositions.Values.Min(); double step = _isAscending ? HorizontalBarSpacing : -HorizontalBarSpacing; int stepCount = 1; while (true) { double currentHeight = _isAscending ? firstBarHeight + (stepCount * HorizontalBarSpacing) : firstBarHeight - (stepCount * HorizontalBarSpacing); if (_isAscending && currentHeight > maxHeight + Tolerance) break; if (!_isAscending && currentHeight < maxHeight - Tolerance) break; double topGap = _isAscending ? (maxHeight - currentHeight) : (currentHeight - maxHeight); if (topGap < MinTopGap) break; barHeights.Add(currentHeight); stepCount++; } } catch (System.Exception ex) { _ed.WriteMessage($"\n计算横杆高度错误: {ex.Message}"); } return barHeights; } private void AddDimensions(Transaction tr, BlockTableRecord btr, Database db, double baseElev) { try { DimensionPoleSpacing(tr, btr, db, baseElev); DimensionBarSpacing(tr, btr, db, baseElev); AddDimensionLeaders(tr, btr, db, baseElev); } catch (System.Exception ex) { _ed.WriteMessage($"\n添加尺寸标注错误: {ex.Message}"); } } private void DimensionPoleSpacing(Transaction tr, BlockTableRecord btr, Database db, double baseElev) { if (_poleBasePositions.Count < 2) return; var positions = _poleBasePositions.Keys.OrderBy(x => x).ToList(); double dimensionY = baseElev - DimensionOffset; for (int i = 0; i < positions.Count - 1; i++) { double x1 = positions[i]; double x2 = positions[i + 1]; double distance = Math.Abs(x2 - x1); using (AlignedDimension dim = new AlignedDimension()) { dim.XLine1Point = new Point3d(x1, dimensionY, 0); dim.XLine2Point = new Point3d(x2, dimensionY, 0); dim.DimLinePoint = new Point3d((x1 + x2) / 2, dimensionY - 50, 0); dim.DimensionStyle = db.Dimstyle; btr.AppendEntity(dim); tr.AddNewlyCreatedDBObject(dim, true); } } } private void DimensionBarSpacing(Transaction tr, BlockTableRecord btr, Database db, double baseElev) { if (_poleBasePositions.Count == 0) return; double firstPoleX = _poleBasePositions.Keys.OrderBy(x => x).First(); double dimensionX = firstPoleX - DimensionOffset; List<double> barHeights = CalculateBarHeightsForDimension(baseElev); barHeights.Sort(); for (int i = 0; i < barHeights.Count - 1; i++) { double y1 = barHeights[i]; double y2 = barHeights[i + 1]; using (AlignedDimension dim = new AlignedDimension()) { dim.XLine1Point = new Point3d(dimensionX, y1, 0); dim.XLine2Point = new Point3d(dimensionX, y2, 0); dim.DimLinePoint = new Point3d(dimensionX - 50, (y1 + y2) / 2, 0); dim.DimensionStyle = db.Dimstyle; btr.AppendEntity(dim); tr.AddNewlyCreatedDBObject(dim, true); } } } private void AddDimensionLeaders(Transaction tr, BlockTableRecord btr, Database db, double baseElev) { try { if (_poleBasePositions.Count > 0) { var polePositions = _poleBasePositions.Keys.OrderBy(x => x).ToList(); double firstPoleX = polePositions.First(); double dimensionX = firstPoleX - DimensionOffset; var barHeights = CalculateBarHeightsForDimension(baseElev); foreach (double height in barHeights) { using (Leader leader = new Leader()) { leader.AppendVertex(new Point3d(firstPoleX, height, 0)); leader.AppendVertex(new Point3d(dimensionX, height, 0)); leader.DimensionStyle = db.Dimstyle; btr.AppendEntity(leader); tr.AddNewlyCreatedDBObject(leader, true); } } } } catch (System.Exception ex) { _ed.WriteMessage($"\n添加标注引线错误: {ex.Message}"); } } private List<double> CalculateBarHeightsForDimension(double baseElev) { var barHeights = new List<double>(); try { double firstBarHeight = _isAscending ? baseElev + FirstBarHeight : baseElev - FirstBarHeight; barHeights.Add(firstBarHeight); double maxHeight = _isAscending ? _topDiskPositions.Values.Max() : _topDiskPositions.Values.Min(); double step = _isAscending ? HorizontalBarSpacing : -HorizontalBarSpacing; int stepCount = 1; while (true) { double currentHeight = _isAscending ? firstBarHeight + (stepCount * HorizontalBarSpacing) : firstBarHeight - (stepCount * HorizontalBarSpacing); if (_isAscending && currentHeight > maxHeight + Tolerance) break; if (!_isAscending && currentHeight < maxHeight - Tolerance) break; double topGap = _isAscending ? (maxHeight - currentHeight) : (currentHeight - maxHeight); if (topGap < MinTopGap) break; barHeights.Add(currentHeight); stepCount++; } } catch (System.Exception ex) { _ed.WriteMessage($"\n计算标注高度错误: {ex.Message}"); } return barHeights; } private bool HasDiskAtHeight(double x, double height, double tolerance) { if (!_diskPositions.TryGetValue(x, out List<double> heights)) return false; return heights.Any(h => Math.Abs(h - height) <= tolerance); } private double? FindNearestDiskBelow(double x, double height, double maxDistance) { if (!_diskPositions.TryGetValue(x, out List<double> heights)) return null; var belowHeights = heights .Where(h => (_isAscending && h <= height) || (!_isAscending && h >= height)) .ToList(); if (!belowHeights.Any()) return null; var closest = belowHeights .OrderBy(h => Math.Abs(h - height)) .First(); if (Math.Abs(closest - height) <= maxDistance) return closest; return null; } private int GetBestBarSize(double distance) { if (distance <= 0) return 0; int[] validSizes = { 300, 600, 900, 1200, 1500, 1800 }; return validSizes .Where(s => s >= distance * 0.8 && s <= distance * 1.2) .OrderBy(s => Math.Abs(s - distance)) .FirstOrDefault(); } private bool IsOnTopControlLine(double x, double y) { if (_topControlLine == null) return false; try { double controlY = GetElevationAtX(x); return Math.Abs(controlY - y) <= TopControlLineTolerance; } catch (System.Exception ex) { _ed.WriteMessage($"\n检查控制线位置错误: {ex.Message}"); return false; } } private double? FindNearestPole(double x, List<double> polePositions) { if (polePositions == null || polePositions.Count == 0) return null; // 找到最近的立杆位置 return polePositions .OrderBy(p => Math.Abs(p - x)) .FirstOrDefault(); } private void InsertBlock(Transaction tr, BlockTableRecord btr, BlockTable bt, string blockName, double x, double y, double rotation = 0) { if (!bt.Has(blockName)) { _ed.WriteMessage($"\n图块不存在: {blockName}"); return; } try { // 特殊部件(顶托和螺母)不进行高度验证 if (!blockName.Contains("顶托") && !blockName.Contains("螺母")) { double controlY = GetElevationAtX(x); bool isValid = _isAscending ? (y <= controlY - MinTopGap) : (y >= controlY + MinTopGap); if (!isValid) { _ed.WriteMessage($"\n跳过无效位置: {blockName} @ ({x}, {y})"); return; } } BlockReference bref = new BlockReference(new Point3d(x, y, 0), bt[blockName]); bref.Rotation = rotation; btr.AppendEntity(bref); tr.AddNewlyCreatedDBObject(bref, true); // 调试日志 if (blockName.Contains("顶托")) _ed.WriteMessage($"\n插入顶托: ({x}, {y})"); } catch (System.Exception ex) { _ed.WriteMessage($"\n插入图块 {blockName} 错误: {ex.Message}"); } } // 插入横杆块 private void InsertHorizontalBarBlock(Transaction tr, BlockTableRecord btr, BlockTable bt, string blockName, double x, double y, double rotation = 0) { if (!bt.Has(blockName)) { _ed.WriteMessage($"\n图块不存在: {blockName}"); return; } try { double controlY = GetElevationAtX(x); bool isValid = _isAscending ? (y <= controlY - MinTopGap) : (y >= controlY + MinTopGap); if (!isValid) { _ed.WriteMessage($"\n跳过无效位置: {blockName} @ ({x}, {y})"); return; } BlockReference bref = new BlockReference(new Point3d(x, y, 0), bt[blockName]); bref.Rotation = rotation; btr.AppendEntity(bref); tr.AddNewlyCreatedDBObject(bref, true); // 记录插入的横杆 _insertedHorizontalBars.Add(bref.ObjectId); } catch (System.Exception ex) { _ed.WriteMessage($"\n插入横杆图块 {blockName} 错误: {ex.Message}"); } } // 插入斜拉杆块(应用镜像变换) private void InsertXieBarBlock( Transaction tr, BlockTableRecord btr, BlockTable bt, string blockName, double x, double y, double rotation, Matrix3d mirrorMatrix) { try { if (!bt.Has(blockName)) { _ed.WriteMessage($"\n图块不存在: {blockName}"); return; } BlockReference bref = new BlockReference(new Point3d(x, y, 0), bt[blockName]); bref.Rotation = rotation; // 应用镜像变换 bref.TransformBy(mirrorMatrix); btr.AppendEntity(bref); tr.AddNewlyCreatedDBObject(bref, true); // 记录插入的斜拉杆 _insertedXieBars.Add(bref.ObjectId); } catch (System.Exception ex) { _ed.WriteMessage($"\n插入斜拉杆图块 {blockName} 错误: {ex.Message}"); } } // 获取最近的连接盘高度 private double? GetNearestDiskHeight(double x, double targetHeight, double tolerance) { try { if (!_diskPositions.TryGetValue(x, out List<double> heights) || heights.Count == 0) { _ed.WriteMessage($"\n警告:立杆{x}未记录连接盘位置"); return null; } // 查找最接近的高度 double? closestHeight = null; double minDiff = double.MaxValue; foreach (double h in heights) { double diff = Math.Abs(h - targetHeight); if (diff < minDiff) { minDiff = diff; closestHeight = h; } } if (minDiff > tolerance) { _ed.WriteMessage($"\n警告:立杆{x}在高度{targetHeight}附近未找到连接盘,最小差距={minDiff}"); return null; } return closestHeight; } catch (System.Exception ex) { _ed.WriteMessage($"\n获取连接盘高度错误: {ex.Message}"); return null; } } } } CS1026应输入450行出现问题 修改一套完整的代码
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值