|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
namespace Mesnac.Basic
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 数据处理器
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class DataProcessor
|
|
|
|
|
{
|
|
|
|
|
#region 获取浮点数值的有效小数位数
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取浮点数值的有效小数位数
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value">浮点数值</param>
|
|
|
|
|
/// <param name="maxPrecision">允许返回的最大小数位数</param>
|
|
|
|
|
/// <returns>返回有效小数位数</returns>
|
|
|
|
|
public static int GetValidPrecision(object value, int maxPrecision)
|
|
|
|
|
{
|
|
|
|
|
if (DataProcessor.IsNullOrEmpty(value))
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (value.ToString().IndexOf(".") == -1)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
string strValue = value.ToString();
|
|
|
|
|
string precision = strValue.Substring(strValue.IndexOf(".") + 1);
|
|
|
|
|
int cnt = 0; //保存末尾0的个数
|
|
|
|
|
for (int i = precision.Length - 1; i > 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (precision.ToCharArray()[i] == '0')
|
|
|
|
|
{
|
|
|
|
|
cnt++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
int result = precision.Length - cnt; //为有效小数位数
|
|
|
|
|
if (result > maxPrecision)
|
|
|
|
|
{
|
|
|
|
|
return maxPrecision;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 对数据行字段取值方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取byte数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static byte RowValue(DataRow dr, string field, byte defaultValue)
|
|
|
|
|
{
|
|
|
|
|
byte Result = defaultValue;
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (byte.TryParse(dr[field].ToString(), out Result))
|
|
|
|
|
{
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取Short数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static short RowValue(DataRow dr, string field, short defaultValue)
|
|
|
|
|
{
|
|
|
|
|
short Result = defaultValue;
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (short.TryParse(dr[field].ToString(), out Result))
|
|
|
|
|
{
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取整型数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static int RowValue(DataRow dr, string field, int defaultValue)
|
|
|
|
|
{
|
|
|
|
|
int Result = defaultValue;
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (int.TryParse(dr[field].ToString(), out Result))
|
|
|
|
|
{
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取float数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static float RowValue(DataRow dr, string field, float defaultValue)
|
|
|
|
|
{
|
|
|
|
|
float Result = defaultValue;
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (float.TryParse(dr[field].ToString(), out Result))
|
|
|
|
|
{
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取double数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static double RowValue(DataRow dr, string field, double defaultValue)
|
|
|
|
|
{
|
|
|
|
|
double Result = defaultValue;
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (double.TryParse(dr[field].ToString(), out Result))
|
|
|
|
|
{
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取decimal数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static decimal RowValue(DataRow dr, string field, decimal defaultValue)
|
|
|
|
|
{
|
|
|
|
|
decimal Result = defaultValue;
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (decimal.TryParse(dr[field].ToString(), out Result))
|
|
|
|
|
{
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取DateTime数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static DateTime RowValue(DataRow dr, string field, DateTime defaultValue)
|
|
|
|
|
{
|
|
|
|
|
DateTime Result = defaultValue;
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (DateTime.TryParse(dr[field].ToString(), out Result))
|
|
|
|
|
{
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取字符串数据列的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dr"></param>
|
|
|
|
|
/// <param name="field"></param>
|
|
|
|
|
/// <param name="defaultValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string RowValue(DataRow dr, string field, string defaultValue)
|
|
|
|
|
{
|
|
|
|
|
if (dr.Table.Columns.Contains(field))
|
|
|
|
|
{
|
|
|
|
|
if (dr[field] != null && dr[field] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
return dr[field].ToString().Trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
|
|
|
|
|
}
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取数组的异或校验值
|
|
|
|
|
|
|
|
|
|
#region 获取数组的异或校验值(第1个元素与第2个元素异或,结果与第3个元素异或,直到最后一个元素)
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取数组的异或校验值(第1个元素与第2个元素异或,结果与第3个元素异或,指导最后一个元素)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="values">数组参数</param>
|
|
|
|
|
/// <returns>返回异或校验值</returns>
|
|
|
|
|
public static Int16 GetXorCheckValue(Int16[] values)
|
|
|
|
|
{
|
|
|
|
|
if (values == null || values.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (values.Length == 1)
|
|
|
|
|
{
|
|
|
|
|
return values[0];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Int16 result = (Int16)(values[0] ^ values[1]);
|
|
|
|
|
for (int i = 2; i < values.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
result = (Int16)(result ^ values[i]);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取数组的异或校验值(第1个元素与第2个元素异或,结果与第3个元素异或,指导最后一个元素)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="values">数组参数</param>
|
|
|
|
|
/// <returns>返回异或校验值</returns>
|
|
|
|
|
public static object GetXorCheckValue(object[] values)
|
|
|
|
|
{
|
|
|
|
|
if (values == null || values.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (values.Length == 1)
|
|
|
|
|
{
|
|
|
|
|
return values[0];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Int16 result = (Int16)(Convert.ToInt16(values[0]) ^ Convert.ToInt16(values[1]));
|
|
|
|
|
for (int i = 2; i < values.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
result = (Int16)(Convert.ToInt16(result) ^ Convert.ToInt16(values[i]));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取数组的异或校验值(第一个参数与数组第一个元素异或,结果与第2个元素异或,直到最后一个元素)
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取数组的异或校验值(第一个参数与数组第一个元素异或,结果与第2个元素异或,直到最后一个元素)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="param">起始参数</param>
|
|
|
|
|
/// <param name="values">数组元素</param>
|
|
|
|
|
/// <returns>返回异或校验值</returns>
|
|
|
|
|
public static Int16 GetXorCheckValueByParm(Int16 param, Int16[] values)
|
|
|
|
|
{
|
|
|
|
|
if (values == null || values.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return param;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Int16 result = param;
|
|
|
|
|
for (int i = 0; i < values.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
result = (Int16)(result ^ values[i]);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取数组的异或校验值(第一个参数与数组第一个元素异或,结果与第2个元素异或,直到最后一个元素)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="param">起始参数</param>
|
|
|
|
|
/// <param name="values">数组元素</param>
|
|
|
|
|
/// <returns>返回异或校验值</returns>
|
|
|
|
|
public static object GetXorCheckValueByParm(object param, object[] values)
|
|
|
|
|
{
|
|
|
|
|
if (values == null || values.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return param;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Int16 result = Convert.ToInt16(param);
|
|
|
|
|
for (int i = 0; i < values.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
result = (Int16)(Convert.ToInt16(result) ^ Convert.ToInt16(values[i]));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 判断2个数组元素值是否相同
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判断2个数组元素值是否相同
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="arr1">数组1</param>
|
|
|
|
|
/// <param name="arr2">数组2</param>
|
|
|
|
|
/// <returns>相同返回true,不同返回false</returns>
|
|
|
|
|
public static bool IsSameArrayValue(object[] arr1, object[] arr2)
|
|
|
|
|
{
|
|
|
|
|
if (arr1.Length != arr2.Length)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
bool result = true;
|
|
|
|
|
for (int i = 0; i < arr1.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!arr1[i].Equals(arr2[i]))
|
|
|
|
|
{
|
|
|
|
|
result = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 克隆DataTable及数据的方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 克隆DataTable及数据的方法
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dt">要克隆的数据表</param>
|
|
|
|
|
/// <returns>返回克隆以后的数据表</returns>
|
|
|
|
|
public static DataTable Clone(DataTable dt)
|
|
|
|
|
{
|
|
|
|
|
DataTable dt2 = dt.Clone();
|
|
|
|
|
foreach (DataRow dr in dt.Rows)
|
|
|
|
|
{
|
|
|
|
|
DataRow dr2 = dt2.NewRow();
|
|
|
|
|
foreach (DataColumn dc in dt.Columns)
|
|
|
|
|
{
|
|
|
|
|
dr2[dc.ColumnName] = dr[dc.ColumnName];
|
|
|
|
|
}
|
|
|
|
|
dt2.Rows.Add(dr2);
|
|
|
|
|
}
|
|
|
|
|
return dt2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 从DataGridView控件获取DataTable数据
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 从DataGridView控件获取DataTable数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="grid"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static DataTable GetDataTableFromGridView(DataGridView grid)
|
|
|
|
|
{
|
|
|
|
|
DataTable dt = grid.DataSource as DataTable;
|
|
|
|
|
if (dt != null)
|
|
|
|
|
{
|
|
|
|
|
DataTable table = dt.Clone();
|
|
|
|
|
foreach(DataGridViewRow dgvRow in grid.Rows)
|
|
|
|
|
{
|
|
|
|
|
DataRow row = table.NewRow();
|
|
|
|
|
foreach(DataGridViewColumn col in grid.Columns)
|
|
|
|
|
{
|
|
|
|
|
row[col.DataPropertyName] = dgvRow.Cells[col.Name].Value;
|
|
|
|
|
}
|
|
|
|
|
table.Rows.Add(row);
|
|
|
|
|
}
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 格式化小数位数
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 格式化小数位数
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="floatValue">要格式化的小数对象</param>
|
|
|
|
|
/// <param name="maxPrecision">保留的最大小数位数</param>
|
|
|
|
|
/// <returns>返回格式化后的小数字符串值</returns>
|
|
|
|
|
public static object FormatFloatValue(object floatValue, int maxPrecision)
|
|
|
|
|
{
|
|
|
|
|
if (IsNullOrEmpty(floatValue))
|
|
|
|
|
{
|
|
|
|
|
return String.Empty;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int intPrecision = GetValidPrecision(floatValue, maxPrecision);
|
|
|
|
|
return String.Format("{0:f" + intPrecision + "}", floatValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 格式化DataTable中小数位数
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 格式化DataTable
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dt">要格式化的DataTable对象</param>
|
|
|
|
|
/// <param name="noFormatColumns">排除在格式化之外的列</param>
|
|
|
|
|
/// <param name="maxPrecision">保留的最大小数位数</param>
|
|
|
|
|
/// <returns>返回格式化后的DataTable对象</returns>
|
|
|
|
|
public static DataTable FormatDataTable(DataTable dt, List<string> noFormatColumns, int maxPrecision)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < dt.Rows.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
foreach (DataColumn dc in dt.Columns)
|
|
|
|
|
{
|
|
|
|
|
if (dc.DataType == typeof(double?) ||
|
|
|
|
|
dc.DataType == typeof(double) ||
|
|
|
|
|
dc.DataType == typeof(float?) ||
|
|
|
|
|
dc.DataType == typeof(float) ||
|
|
|
|
|
dc.DataType == typeof(decimal?) ||
|
|
|
|
|
dc.DataType == typeof(decimal) ||
|
|
|
|
|
dc.DataType == typeof(int?) ||
|
|
|
|
|
dc.DataType == typeof(int))
|
|
|
|
|
{
|
|
|
|
|
if (dt.Rows[i][dc] != null && dt.Rows[i][dc] != DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
if (noFormatColumns != null && noFormatColumns.Contains(dc.ColumnName))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
double d = 0.0;
|
|
|
|
|
string ss = dt.Rows[i][dc].ToString();
|
|
|
|
|
if (double.TryParse(ss, out d) && d == 0)
|
|
|
|
|
{
|
|
|
|
|
dt.Rows[i][dc] = DBNull.Value;
|
|
|
|
|
}
|
|
|
|
|
else if (dc.DataType != typeof(int))
|
|
|
|
|
{
|
|
|
|
|
int intPrecision = GetValidPrecision(dt.Rows[i][dc], maxPrecision);
|
|
|
|
|
dt.Rows[i][dc] = String.Format("{0:f" + intPrecision + "}", dt.Rows[i][dc]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return dt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 清除DataGridView中的选中行
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 清除DataGridView中的选中行
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="grid"></param>
|
|
|
|
|
public static void ClearSelectedStatus(DataGridView grid)
|
|
|
|
|
{
|
|
|
|
|
if (grid != null && grid.Visible)
|
|
|
|
|
{
|
|
|
|
|
foreach (DataGridViewRow row in grid.Rows)
|
|
|
|
|
{
|
|
|
|
|
if (row.Selected)
|
|
|
|
|
{
|
|
|
|
|
row.Selected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 注册清除DataGridView中的选中行事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="grid"></param>
|
|
|
|
|
public static void RegistClearSelectedEvent(DataGridView grid)
|
|
|
|
|
{
|
|
|
|
|
grid.VisibleChanged -= grid_VisibleChanged;
|
|
|
|
|
grid.VisibleChanged += grid_VisibleChanged;
|
|
|
|
|
grid.CellDoubleClick -= grid_CellDoubleClick;
|
|
|
|
|
grid.CellDoubleClick += grid_CellDoubleClick;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void grid_VisibleChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
DataGridView grid = sender as DataGridView;
|
|
|
|
|
if (grid != null && grid.Visible)
|
|
|
|
|
{
|
|
|
|
|
foreach (DataGridViewRow row in grid.Rows)
|
|
|
|
|
{
|
|
|
|
|
if (row.Selected)
|
|
|
|
|
{
|
|
|
|
|
row.Selected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void grid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
DataGridView grid = sender as DataGridView;
|
|
|
|
|
if (grid != null && grid.Visible)
|
|
|
|
|
{
|
|
|
|
|
foreach (DataGridViewRow row in grid.Rows)
|
|
|
|
|
{
|
|
|
|
|
if (row.Selected)
|
|
|
|
|
{
|
|
|
|
|
row.Selected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region "按字符串位数补0"
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 按字符串位数补0
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="CharTxt">字符串</param>
|
|
|
|
|
/// <param name="CharLen">字符长度</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string FillZero(string CharTxt, int CharLen)
|
|
|
|
|
{
|
|
|
|
|
if (CharTxt.Length < CharLen)
|
|
|
|
|
{
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
for (int i = 0; i < CharLen - CharTxt.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
sb.Append("0");
|
|
|
|
|
}
|
|
|
|
|
sb.Append(CharTxt);
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return CharTxt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 判断字符串是否为纯数字
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判断字符串是否为纯数字
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="str">要判断的字符串</param>
|
|
|
|
|
/// <returns>是纯数字返回true,否则返回false</returns>
|
|
|
|
|
public static bool IsNumeric(string str) //接收一个string类型的参数,保存到str里
|
|
|
|
|
{
|
|
|
|
|
if (str == null || str.Length == 0) //验证这个参数是否为空
|
|
|
|
|
return false; //是,就返回False
|
|
|
|
|
ASCIIEncoding ascii = new ASCIIEncoding();//new ASCIIEncoding 的实例
|
|
|
|
|
byte[] bytestr = ascii.GetBytes(str); //把string类型的参数保存到数组里
|
|
|
|
|
|
|
|
|
|
foreach (byte c in bytestr) //遍历这个数组里的内容
|
|
|
|
|
{
|
|
|
|
|
if (c < 48 || c > 57) //判断是否为数字
|
|
|
|
|
{
|
|
|
|
|
return false; //不是,就返回False
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true; //是,就返回True
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 判断是否为空
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判断是否为空
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value">要判断的对象</param>
|
|
|
|
|
/// <returns>为空返回true,否则返回false</returns>
|
|
|
|
|
public static bool IsNullOrEmpty(object value)
|
|
|
|
|
{
|
|
|
|
|
if (value == null || value == DBNull.Value || string.IsNullOrWhiteSpace(value.ToString()))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 合并消息列表
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 合并消息列表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="msgList">要合并的消息列表</param>
|
|
|
|
|
/// <returns>返回合并的消息字符串</returns>
|
|
|
|
|
public static string CombineMsgList(List<string> msgList)
|
|
|
|
|
{
|
|
|
|
|
if (msgList != null && msgList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
foreach (string msg in msgList)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(msg);
|
|
|
|
|
}
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
return String.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 合并消息列表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="msgList">要合并的消息列表</param>
|
|
|
|
|
/// <returns>返回合并的消息字符串</returns>
|
|
|
|
|
public static string CombineMsgList(List<string> msgList, string split)
|
|
|
|
|
{
|
|
|
|
|
if (msgList != null && msgList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
foreach (string msg in msgList)
|
|
|
|
|
{
|
|
|
|
|
if (String.IsNullOrEmpty(sb.ToString()))
|
|
|
|
|
{
|
|
|
|
|
sb.Append(msg);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sb.Append(split);
|
|
|
|
|
sb.Append(msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
return String.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把从PLC读取的buff数组转换为指定类型数据
|
|
|
|
|
|
|
|
|
|
#region 把Int16[]转换为Int32类型变量
|
|
|
|
|
|
|
|
|
|
#region 西门子PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为Int32类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回Int32类型值</returns>
|
|
|
|
|
public static Int32 ToSiemensInt32(Int16[] buff)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (buff == null)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败,原因buff为NULL!"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (buff.Length != 2)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败,原因buff.Length={0}应为2!", buff.Length));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Int16 int16Value0 = Convert.ToInt16(buff[0]);
|
|
|
|
|
Int16 int16Value1 = Convert.ToInt16(buff[1]);
|
|
|
|
|
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
|
|
|
|
|
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
|
|
|
|
|
byte[] resultValues = new byte[4];
|
|
|
|
|
resultValues[0] = byteValues1[0];
|
|
|
|
|
resultValues[1] = byteValues1[1];
|
|
|
|
|
resultValues[2] = byteValues0[0];
|
|
|
|
|
resultValues[3] = byteValues0[1];
|
|
|
|
|
Int32 result = BitConverter.ToInt32(resultValues, 0);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为Int32类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回Int32类型值</returns>
|
|
|
|
|
public static Int32 ToSiemensInt32(int[] buff)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buffResult = new Int16[buff.Length];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buffResult[i] = Convert.ToInt16(buff[i]);
|
|
|
|
|
}
|
|
|
|
|
return ToSiemensInt32(buffResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把2个Int16类型的数转换为Int32类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff0">第一个Int16类型的参数</param>
|
|
|
|
|
/// <param name="buff1">第二个Int16类型的参数</param>
|
|
|
|
|
/// <returns>返回对应Int32类型的值</returns>
|
|
|
|
|
public static Int32 ToSiemensInt32(Int16 buff0, Int16 buff1)
|
|
|
|
|
{
|
|
|
|
|
Int16 int16Value0 = Convert.ToInt16(buff0);
|
|
|
|
|
Int16 int16Value1 = Convert.ToInt16(buff1);
|
|
|
|
|
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
|
|
|
|
|
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
|
|
|
|
|
byte[] resultValues = new byte[4];
|
|
|
|
|
resultValues[0] = byteValues1[0];
|
|
|
|
|
resultValues[1] = byteValues1[1];
|
|
|
|
|
resultValues[2] = byteValues0[0];
|
|
|
|
|
resultValues[3] = byteValues0[1];
|
|
|
|
|
Int32 result = BitConverter.ToInt32(resultValues, 0);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 其他PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为Int32类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回Int32类型值</returns>
|
|
|
|
|
public static Int32 ToInt32(Int16[] buff)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (buff == null)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败,原因buff为NULL!"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (buff.Length != 2)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败,原因buff.Length={0}应为2!", buff.Length));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Int16 int16Value0 = Convert.ToInt16(buff[0]);
|
|
|
|
|
Int16 int16Value1 = Convert.ToInt16(buff[1]);
|
|
|
|
|
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
|
|
|
|
|
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
|
|
|
|
|
byte[] resultValues = new byte[4];
|
|
|
|
|
resultValues[0] = byteValues0[0];
|
|
|
|
|
resultValues[1] = byteValues0[1];
|
|
|
|
|
resultValues[2] = byteValues1[0];
|
|
|
|
|
resultValues[3] = byteValues1[1];
|
|
|
|
|
Int32 result = BitConverter.ToInt32(resultValues, 0);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为Int32类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回Int32类型值</returns>
|
|
|
|
|
public static Int32 ToInt32(int[] buff)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buffResult = new Int16[buff.Length];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buffResult[i] = Convert.ToInt16(buff[i]);
|
|
|
|
|
}
|
|
|
|
|
return ToInt32(buffResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把2个Int16类型的数转换为Int32类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff0">第一个Int16类型的参数</param>
|
|
|
|
|
/// <param name="buff1">第二个Int16类型的参数</param>
|
|
|
|
|
/// <returns>返回对应Int32类型的值</returns>
|
|
|
|
|
public static Int32 ToInt32(Int16 buff0, Int16 buff1)
|
|
|
|
|
{
|
|
|
|
|
Int16 int16Value0 = Convert.ToInt16(buff0);
|
|
|
|
|
Int16 int16Value1 = Convert.ToInt16(buff1);
|
|
|
|
|
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
|
|
|
|
|
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
|
|
|
|
|
byte[] resultValues = new byte[4];
|
|
|
|
|
resultValues[0] = byteValues0[0];
|
|
|
|
|
resultValues[1] = byteValues0[1];
|
|
|
|
|
resultValues[2] = byteValues1[0];
|
|
|
|
|
resultValues[3] = byteValues1[1];
|
|
|
|
|
Int32 result = BitConverter.ToInt32(resultValues, 0);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion-
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把Int16[]转换为float类型变量
|
|
|
|
|
|
|
|
|
|
#region 西门子PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为float类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回float类型值</returns>
|
|
|
|
|
public static float ToSiemensFloat(Int16[] buff)
|
|
|
|
|
{
|
|
|
|
|
if (buff == null)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败,原因buff为NULL!"));
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
if (buff.Length != 2)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败,原因buff.Length={0}应为2!", buff.Length));
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte[] buff0Arr = BitConverter.GetBytes(buff[0]);
|
|
|
|
|
byte[] buff1Arr = BitConverter.GetBytes(buff[1]);
|
|
|
|
|
|
|
|
|
|
List<byte> lv = new List<byte>();
|
|
|
|
|
lv.Add(buff0Arr[1]);
|
|
|
|
|
lv.Add(buff0Arr[0]);
|
|
|
|
|
lv.Add(buff1Arr[1]);
|
|
|
|
|
lv.Add(buff1Arr[0]);
|
|
|
|
|
lv.Reverse();
|
|
|
|
|
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为float类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回float类型值</returns>
|
|
|
|
|
public static float ToSiemensFloat(int[] buff)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buffResult = new Int16[buff.Length];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buffResult[i] = Convert.ToInt16(buff[i]);
|
|
|
|
|
}
|
|
|
|
|
return ToSiemensFloat(buffResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把2个Int16类型的整数转换为float类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff0">第一个Int16类型参数</param>
|
|
|
|
|
/// <param name="buff1">第二个Int16类型参数</param>
|
|
|
|
|
/// <returns>返回对应float类型值</returns>
|
|
|
|
|
public static float ToSiemensFloat(Int16 buff0, Int16 buff1)
|
|
|
|
|
{
|
|
|
|
|
byte[] buff0Arr = BitConverter.GetBytes(buff0);
|
|
|
|
|
byte[] buff1Arr = BitConverter.GetBytes(buff1);
|
|
|
|
|
|
|
|
|
|
List<byte> lv = new List<byte>();
|
|
|
|
|
lv.Add(buff0Arr[1]);
|
|
|
|
|
lv.Add(buff0Arr[0]);
|
|
|
|
|
lv.Add(buff1Arr[1]);
|
|
|
|
|
lv.Add(buff1Arr[0]);
|
|
|
|
|
lv.Reverse();
|
|
|
|
|
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 其他PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为float类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回float类型值</returns>
|
|
|
|
|
public static float ToFloat(Int16[] buff)
|
|
|
|
|
{
|
|
|
|
|
if (buff == null)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败,原因buff为NULL!"));
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
if (buff.Length != 2)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败,原因buff.Length={0}应为2!", buff.Length));
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte[] buff0Arr = BitConverter.GetBytes(buff[0]);
|
|
|
|
|
byte[] buff1Arr = BitConverter.GetBytes(buff[1]);
|
|
|
|
|
|
|
|
|
|
List<byte> lv = new List<byte>();
|
|
|
|
|
lv.Add(buff0Arr[0]);
|
|
|
|
|
lv.Add(buff0Arr[1]);
|
|
|
|
|
lv.Add(buff1Arr[0]);
|
|
|
|
|
lv.Add(buff1Arr[1]);
|
|
|
|
|
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把长度为2的Int16类型的数组转换为float类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">长度为2的Int16类型的数组</param>
|
|
|
|
|
/// <returns>返回float类型值</returns>
|
|
|
|
|
public static float ToFloat(int[] buff)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buffResult = new Int16[buff.Length];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buffResult[i] = Convert.ToInt16(buff[i]);
|
|
|
|
|
}
|
|
|
|
|
return ToFloat(buffResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把2个Int16类型的整数转换为float类型的值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff0">第一个Int16类型参数</param>
|
|
|
|
|
/// <param name="buff1">第二个Int16类型参数</param>
|
|
|
|
|
/// <returns>返回对应float类型值</returns>
|
|
|
|
|
public static float ToFloat(Int16 buff0, Int16 buff1)
|
|
|
|
|
{
|
|
|
|
|
byte[] buff0Arr = BitConverter.GetBytes(buff0);
|
|
|
|
|
byte[] buff1Arr = BitConverter.GetBytes(buff1);
|
|
|
|
|
|
|
|
|
|
List<byte> lv = new List<byte>();
|
|
|
|
|
lv.Add(buff0Arr[0]);
|
|
|
|
|
lv.Add(buff0Arr[1]);
|
|
|
|
|
lv.Add(buff1Arr[0]);
|
|
|
|
|
lv.Add(buff1Arr[1]);
|
|
|
|
|
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把Int16[]转换为string类型变量
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int16[]类型的数组转换为字符串(跳过标识字符串长度的前2个字节)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">Int16类型的数组参数</param>
|
|
|
|
|
/// <returns>返回转换后的字符串值</returns>
|
|
|
|
|
public static string ToString(Int16[] buff)
|
|
|
|
|
{
|
|
|
|
|
if (buff == null || buff.Length <= 2)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为字符串失败,原因buff为NULL!"));
|
|
|
|
|
return String.Empty;
|
|
|
|
|
}
|
|
|
|
|
List<byte> chars = new List<byte>();
|
|
|
|
|
for (int i = 0; i < buff.Length; i++) //跳过标识字符串长度的前2个字节
|
|
|
|
|
{
|
|
|
|
|
chars.AddRange(BitConverter.GetBytes(buff[i]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string Result = string.Empty;
|
|
|
|
|
Result = System.Text.Encoding.Default.GetString(chars.ToArray());
|
|
|
|
|
Result = Result.Replace("\0", string.Empty);
|
|
|
|
|
|
|
|
|
|
return Result.Trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//public static string ToString(Int16[] buff)
|
|
|
|
|
//{
|
|
|
|
|
// if (buff == null || buff.Length <= 2)
|
|
|
|
|
// {
|
|
|
|
|
// ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为字符串失败,原因buff为NULL!"));
|
|
|
|
|
// return String.Empty;
|
|
|
|
|
// }
|
|
|
|
|
// List<byte> chars = new List<byte>();
|
|
|
|
|
// for (int i = 2; i < buff.Length; i++) //跳过标识字符串长度的前2个字节
|
|
|
|
|
// {
|
|
|
|
|
// chars.AddRange(BitConverter.GetBytes(buff[i]));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// string Result = string.Empty;
|
|
|
|
|
// Result = System.Text.Encoding.Default.GetString(chars.ToArray());
|
|
|
|
|
// Result = Result.Replace("\0", string.Empty);
|
|
|
|
|
|
|
|
|
|
// return Result.Trim();
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int16类型的数组转换为字符串(跳过标识字符串长度的前2个字节)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">Int16类型的数组参数</param>
|
|
|
|
|
/// <returns>返回转换后的字符串值</returns>
|
|
|
|
|
public static string ToString1(Int16[] buff)
|
|
|
|
|
{
|
|
|
|
|
if (buff == null || buff.Length <= 2)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为字符串失败,原因buff为NULL!"));
|
|
|
|
|
return String.Empty;
|
|
|
|
|
}
|
|
|
|
|
List<byte> chars = new List<byte>();
|
|
|
|
|
for (int i = 0; i < buff.Length; i++) //跳过标识字符串长度的前2个字节
|
|
|
|
|
{
|
|
|
|
|
chars.AddRange(BitConverter.GetBytes(buff[i]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string Result = string.Empty;
|
|
|
|
|
Result = System.Text.Encoding.Default.GetString(chars.ToArray());
|
|
|
|
|
Result = Result.Replace("\0", string.Empty);
|
|
|
|
|
|
|
|
|
|
return Result.Trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把Int32[]转换为string类型变量
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int32类型的数组转换为字符串
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">Int32类型的数组参数</param>
|
|
|
|
|
/// <returns>返回转换后的字符串值</returns>
|
|
|
|
|
public static string ToString(int[] buff)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buffResult = new Int16[buff.Length];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buffResult[i] = (short)buff[i];
|
|
|
|
|
}
|
|
|
|
|
return ToString(buffResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int32类型的数组转换为字符串
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">Int32类型的数组参数</param>
|
|
|
|
|
/// <returns>返回转换后的字符串值</returns>
|
|
|
|
|
public static string ToString1(int[] buff)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buffResult = new Int16[buff.Length];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buffResult[i] = (short)buff[i];
|
|
|
|
|
}
|
|
|
|
|
return ToString1(buffResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把Int16[]转换为DateTime对象
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int16类型的数组转换为DateTime对性爱那个
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buff">Int16类型的数组参数</param>
|
|
|
|
|
/// <returns>返回转换后的DateTime对象</returns>
|
|
|
|
|
public static DateTime ToDateTime(Int16[] buff)
|
|
|
|
|
{
|
|
|
|
|
if (buff == null)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为DateTime失败,原因buff为NULL!"));
|
|
|
|
|
return new DateTime(1900, 1, 1, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
if (buff.Length != 6)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为DateTime失败,原因buff长度不等于6!"));
|
|
|
|
|
return new DateTime(1900, 1, 1, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
DateTime dateResult = DateTime.Now;
|
|
|
|
|
string strDate = String.Format("{0}-{1}-{2} {3}:{4}:{5}", buff[0], buff[1], buff[2], buff[3], buff[4], buff[5]);
|
|
|
|
|
if (!DateTime.TryParse(strDate, out dateResult))
|
|
|
|
|
{
|
|
|
|
|
dateResult = DateTime.Now;
|
|
|
|
|
//ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为DateTime失败!"));
|
|
|
|
|
}
|
|
|
|
|
return dateResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把系统变量转换为要写入PLC的数据
|
|
|
|
|
|
|
|
|
|
#region 把Int32转换为PLC数据
|
|
|
|
|
|
|
|
|
|
#region 西门子PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int32类型的变量转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value">要转换的Int32类型变量</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static Int16[] ToSiemensPLCInt16Array(Int32 value)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = new Int16[2];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buff[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
byte[] byteValues = BitConverter.GetBytes(value);
|
|
|
|
|
Int16[] intValues = new Int16[2];
|
|
|
|
|
intValues[0] = System.Convert.ToInt16(System.Convert.ToString(byteValues[3], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[2], 2).PadLeft(8, '0'), 2);
|
|
|
|
|
intValues[1] = System.Convert.ToInt16(System.Convert.ToString(byteValues[1], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[0], 2).PadLeft(8, '0'), 2);
|
|
|
|
|
buff[0] = intValues[0];
|
|
|
|
|
buff[1] = intValues[1];
|
|
|
|
|
return buff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int32类型的变量转换为object[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value">要转换的Int32类型的变量</param>
|
|
|
|
|
/// <returns>返回转换后的object[]</returns>
|
|
|
|
|
public static object[] ToSiemensPLCDataArray(Int32 value)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = ToSiemensPLCInt16Array(value);
|
|
|
|
|
object[] result = new object[buff.Length];
|
|
|
|
|
Array.Copy(buff, result, buff.Length);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 其他PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int32类型的变量转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value">要转换的Int32类型变量</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static Int16[] ToPLCInt16Array(Int32 value)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = new Int16[2];
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buff[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
byte[] byteValues = BitConverter.GetBytes(value);
|
|
|
|
|
buff[0] = BitConverter.ToInt16(byteValues, 0);
|
|
|
|
|
buff[1] = BitConverter.ToInt16(byteValues, 2);
|
|
|
|
|
return buff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Int32类型的变量转换为object[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value">要转换的Int32类型的变量</param>
|
|
|
|
|
/// <returns>返回转换后的object[]</returns>
|
|
|
|
|
public static object[] ToPLCDataArray(Int32 value)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = ToPLCInt16Array(value);
|
|
|
|
|
object[] result = new object[buff.Length];
|
|
|
|
|
Array.Copy(buff, result, buff.Length);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把float转换为PLC数据
|
|
|
|
|
|
|
|
|
|
#region 西门子PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把float类型的变量转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fvalue">要转换的float类型的变量</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static Int16[] ToSiemensPLCInt16Array(float fvalue)
|
|
|
|
|
{
|
|
|
|
|
byte[] byteValues = BitConverter.GetBytes(fvalue);
|
|
|
|
|
Int16[] intValues = new Int16[2];
|
|
|
|
|
intValues[0] = System.Convert.ToInt16(System.Convert.ToString(byteValues[3], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[2], 2).PadLeft(8, '0'), 2);
|
|
|
|
|
intValues[1] = System.Convert.ToInt16(System.Convert.ToString(byteValues[1], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[0], 2).PadLeft(8, '0'), 2);
|
|
|
|
|
return intValues;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把float类型的变量转换为object[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fvalue">要转换的float类型的变量</param>
|
|
|
|
|
/// <returns>返回转换后的object[]</returns>
|
|
|
|
|
public static object[] ToSiemensPLCDataArray(float fvalue)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = ToSiemensPLCInt16Array(fvalue);
|
|
|
|
|
object[] buffResult = new object[buff.Length];
|
|
|
|
|
Array.Copy(buff, buffResult, buff.Length);
|
|
|
|
|
return buffResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 其他PLC处理方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把float类型的变量转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fvalue">要转换的float类型的变量</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static Int16[] ToPLCInt16Array(float fvalue)
|
|
|
|
|
{
|
|
|
|
|
byte[] byteValues = BitConverter.GetBytes(fvalue);
|
|
|
|
|
Int16[] intValues = new Int16[2];
|
|
|
|
|
intValues[0] = BitConverter.ToInt16(byteValues, 0);
|
|
|
|
|
intValues[1] = BitConverter.ToInt16(byteValues, 2);
|
|
|
|
|
return intValues;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把float类型的变量转换为object[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fvalue">要转换的float类型的变量</param>
|
|
|
|
|
/// <returns>返回转换后的object[]</returns>
|
|
|
|
|
public static object[] ToPLCDataArray(float fvalue)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = ToPLCInt16Array(fvalue);
|
|
|
|
|
object[] buffResult = new object[buff.Length];
|
|
|
|
|
Array.Copy(buff, buffResult, buff.Length);
|
|
|
|
|
return buffResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把String转换为PLC数据
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把字符串变量转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="str">要转换的字符串变量</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static Int16[] ToPLCInt16Array(string str)
|
|
|
|
|
{
|
|
|
|
|
byte[] temp = System.Text.Encoding.Default.GetBytes(str);
|
|
|
|
|
Int32 charLen = temp.Length;
|
|
|
|
|
object[] lenBuff = ToSiemensPLCDataArray(charLen);
|
|
|
|
|
|
|
|
|
|
Int16[] buff = new Int16[temp.Length / 2 + temp.Length % 2];
|
|
|
|
|
if (temp.Length % 2 == 0)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buff[i] = BitConverter.ToInt16(temp, i * 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
byte[] temp1 = new byte[temp.Length + 1];
|
|
|
|
|
Array.Copy(temp, temp1, temp.Length);
|
|
|
|
|
for (int i = 0; i < buff.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buff[i] = BitConverter.ToInt16(temp1, i * 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//cfm20210804修改
|
|
|
|
|
//Int16[] buffResult = new Int16[buff.Length + lenBuff.Length];
|
|
|
|
|
//Array.Copy(lenBuff, buffResult, lenBuff.Length); //预留2个字节的位置保存字符串的实际长度
|
|
|
|
|
//Array.Copy(buff, 0, buffResult, lenBuff.Length, buff.Length);
|
|
|
|
|
//return buffResult;
|
|
|
|
|
return buff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把字符串变量转换为object[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="str">要转换的字符串变量</param>
|
|
|
|
|
/// <returns>返回转换后的object[]</returns>
|
|
|
|
|
public static object[] ToPLCDataArray(string str)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = ToPLCInt16Array(str);
|
|
|
|
|
object[] buffResult = new object[buff.Length];
|
|
|
|
|
Array.Copy(buff, buffResult, buff.Length);
|
|
|
|
|
return buffResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把字符串变量转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="str">要转换的字符串变量</param>
|
|
|
|
|
/// <param name="length">要补够的长度</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static object[] ToPLCDataArray(string str, int length)
|
|
|
|
|
{
|
|
|
|
|
object[] buff = ToPLCDataArray(str);
|
|
|
|
|
|
|
|
|
|
#region 补够长度
|
|
|
|
|
|
|
|
|
|
object[] buffResult = new object[length];
|
|
|
|
|
for (int i = 0; i < buffResult.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
buffResult[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Array.Copy(buff, buffResult, buff.Length);
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
return buffResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把DateTime转换为PLC数据
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把日期时间对象转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dtNow">要转换的日期时间对象</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static Int16[] ToPLCInt16Array(DateTime dtNow)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = new Int16[] { (short)dtNow.Year, (short)dtNow.Month, (short)dtNow.Day, (short)dtNow.Hour, (short)dtNow.Minute, (short)dtNow.Second };
|
|
|
|
|
return buff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把日期时间对象转换为object[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dtNow">要转换的日期时间对象</param>
|
|
|
|
|
/// <returns>返回转换后的object[]</returns>
|
|
|
|
|
public static object[] ToPLCDataArray(DateTime dtNow)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = ToPLCInt16Array(dtNow);
|
|
|
|
|
|
|
|
|
|
object[] buffResult = new object[buff.Length];
|
|
|
|
|
Array.Copy(buff, buffResult, buff.Length);
|
|
|
|
|
|
|
|
|
|
return buffResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 把Time字符串转换为PLC数据
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Time字符串对象转换为Int16[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="timeStr">要转换的日期时间对象</param>
|
|
|
|
|
/// <returns>返回转换后的Int16[]</returns>
|
|
|
|
|
public static Int16[] ToPLCInt16ArrayFromTimeStr(string timeStr)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = new Int16[] { 0, 0, 0 };
|
|
|
|
|
string[] times = timeStr.Split(new char[] { ':' });
|
|
|
|
|
if (times.Length != 3)
|
|
|
|
|
{
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error("把Time字符串转为Int[]失败,格式不正确,请确保时间是以':'分隔的时、分、秒构成!");
|
|
|
|
|
return buff;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Int16.TryParse(times[0], out buff[0]);
|
|
|
|
|
Int16.TryParse(times[1], out buff[1]);
|
|
|
|
|
Int16.TryParse(times[2], out buff[2]);
|
|
|
|
|
return buff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 把Time字符串对象转换为object[]
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="timeStr">要转换的Time字符串对象</param>
|
|
|
|
|
/// <returns>返回转换后的object[]</returns>
|
|
|
|
|
public static object[] ToPLCDataArrayFromTimeStr(string timeStr)
|
|
|
|
|
{
|
|
|
|
|
Int16[] buff = ToPLCInt16ArrayFromTimeStr(timeStr);
|
|
|
|
|
|
|
|
|
|
object[] buffResult = new object[buff.Length];
|
|
|
|
|
Array.Copy(buff, buffResult, buff.Length);
|
|
|
|
|
|
|
|
|
|
return buffResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 类型转换
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 将一个对象转换为指定类型
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="obj">待转换的对象</param>
|
|
|
|
|
/// <param name="type">目标类型</param>
|
|
|
|
|
/// <returns>转换后的对象</returns>
|
|
|
|
|
public static object ChangeType(object obj, Type type)
|
|
|
|
|
{
|
|
|
|
|
if (type == null) return obj;
|
|
|
|
|
if (obj == null) return type.IsValueType ? Activator.CreateInstance(type) : null;
|
|
|
|
|
|
|
|
|
|
Type underlyingType = Nullable.GetUnderlyingType(type);
|
|
|
|
|
if (type.IsAssignableFrom(obj.GetType())) // 如果待转换对象的类型与目标类型兼容,则无需转换
|
|
|
|
|
{
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
else if ((underlyingType ?? type).IsEnum) // 如果待转换的对象的基类型为枚举
|
|
|
|
|
{
|
|
|
|
|
if (underlyingType != null && string.IsNullOrEmpty(obj.ToString())) // 如果目标类型为可空枚举,并且待转换对象为null 则直接返回null值
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Enum.Parse(underlyingType ?? type, obj.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (typeof(IConvertible).IsAssignableFrom(underlyingType ?? type)) // 如果目标类型的基类型实现了IConvertible,则直接转换
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return Convert.ChangeType(obj, underlyingType ?? type, null);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return underlyingType == null ? Activator.CreateInstance(type) : null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TypeConverter converter = TypeDescriptor.GetConverter(type);
|
|
|
|
|
if (converter.CanConvertFrom(obj.GetType()))
|
|
|
|
|
{
|
|
|
|
|
return converter.ConvertFrom(obj);
|
|
|
|
|
}
|
|
|
|
|
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
|
|
|
|
|
if (constructor != null)
|
|
|
|
|
{
|
|
|
|
|
object o = constructor.Invoke(null);
|
|
|
|
|
PropertyInfo[] propertys = type.GetProperties();
|
|
|
|
|
Type oldType = obj.GetType();
|
|
|
|
|
foreach (PropertyInfo property in propertys)
|
|
|
|
|
{
|
|
|
|
|
PropertyInfo p = oldType.GetProperty(property.Name);
|
|
|
|
|
if (property.CanWrite && p != null && p.CanRead)
|
|
|
|
|
{
|
|
|
|
|
property.SetValue(o, ChangeType(p.GetValue(obj, null), property.PropertyType), null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 二进制操作方法
|
|
|
|
|
|
|
|
|
|
#region 二进制位操作
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 对Int16数据的指定起始位指定长度的二进制位赋值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x">源Int16数据</param>
|
|
|
|
|
/// <param name="startIndex">二进制起始位,从0开始(低位->高位)</param>
|
|
|
|
|
/// <param name="length">要操作的长度</param>
|
|
|
|
|
/// <param name="value">要写入的值</param>
|
|
|
|
|
/// <returns>返回二进制操作后的数据</returns>
|
|
|
|
|
public static Int16 SetBitValue(Int16 x, int startIndex, int length, Int16 value)
|
|
|
|
|
{
|
|
|
|
|
int totalLen = 16;
|
|
|
|
|
string original = FillZero(Convert.ToString(x, 2), totalLen);
|
|
|
|
|
if (Convert.ToString(value, 2).Length > length)
|
|
|
|
|
{
|
|
|
|
|
string msg = "对数据的二进制操作失败,要写入的值超过了要操作的二进制长度!";
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error(msg);
|
|
|
|
|
throw new Exception();
|
|
|
|
|
}
|
|
|
|
|
string param = FillZero(Convert.ToString(value, 2), length);
|
|
|
|
|
string result = original.Substring(0, totalLen - (startIndex + length)) + param + original.Substring(totalLen - startIndex);
|
|
|
|
|
return Convert.ToInt16(result, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 对object数据的指定起始位指定长度的二进制位赋值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x">源object数据</param>
|
|
|
|
|
/// <param name="startIndex">二进制起始位,从0开始(低位->高位)</param>
|
|
|
|
|
/// <param name="length">要操作的长度</param>
|
|
|
|
|
/// <param name="value">要写入的值</param>
|
|
|
|
|
/// <returns>返回二进制操作后的数据</returns>
|
|
|
|
|
public static object SetBitValue(object x, int startIndex, int length, object value)
|
|
|
|
|
{
|
|
|
|
|
Int16 intX = Convert.ToInt16(x);
|
|
|
|
|
Int16 intValue = Convert.ToInt16(value);
|
|
|
|
|
return SetBitValue(intX, startIndex, length, intValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 对Int32数据的指定起始位指定长度的二进制位赋值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x">源Int32数据</param>
|
|
|
|
|
/// <param name="startIndex">二进制起始位,从0开始(低位->高位)</param>
|
|
|
|
|
/// <param name="length">要操作的长度</param>
|
|
|
|
|
/// <param name="value">要写入的值</param>
|
|
|
|
|
/// <returns>返回二进制操作后的数据</returns>
|
|
|
|
|
public static Int32 SetBitValue32(Int32 x, int startIndex, int length, Int32 value)
|
|
|
|
|
{
|
|
|
|
|
int totalLen = 32;
|
|
|
|
|
string original = FillZero(Convert.ToString(x, 2), totalLen);
|
|
|
|
|
if (Convert.ToString(value, 2).Length > length)
|
|
|
|
|
{
|
|
|
|
|
string msg = "对数据的二进制操作失败,要写入的值超过了要操作的二进制长度!";
|
|
|
|
|
ICSharpCode.Core.LoggingService<DataProcessor>.Error(msg);
|
|
|
|
|
throw new Exception();
|
|
|
|
|
}
|
|
|
|
|
string param = FillZero(Convert.ToString(value, 2), length);
|
|
|
|
|
string result = original.Substring(0, totalLen - (startIndex + length)) + param + original.Substring(totalLen - startIndex);
|
|
|
|
|
return Convert.ToInt32(result, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 对object数据的指定起始位指定长度的二进制位赋值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x">源object数据</param>
|
|
|
|
|
/// <param name="startIndex">二进制起始位,从0开始(低位->高位)</param>
|
|
|
|
|
/// <param name="length">要操作的长度</param>
|
|
|
|
|
/// <param name="value">要写入的值</param>
|
|
|
|
|
/// <returns>返回二进制操作后的数据</returns>
|
|
|
|
|
public static object SetBitValue32(object x, int startIndex, int length, object value)
|
|
|
|
|
{
|
|
|
|
|
Int32 intX = Convert.ToInt32(x);
|
|
|
|
|
Int32 intValue = Convert.ToInt32(value);
|
|
|
|
|
return SetBitValue32(intX, startIndex, length, intValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 二进制位操作辅助方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 高8位低8位转换(byte[0]byte[1]->byte[1]byte[0])
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="a">要进行高低位转换的Int16类型变量</param>
|
|
|
|
|
/// <returns>返回转换后的值</returns>
|
|
|
|
|
public static Int16 Swap(Int16 a)
|
|
|
|
|
{
|
|
|
|
|
byte[] orignalData = BitConverter.GetBytes(a);
|
|
|
|
|
List<byte> lst = new List<byte>();
|
|
|
|
|
for (int i = 0; i < orignalData.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
lst.Add(orignalData[i]);
|
|
|
|
|
}
|
|
|
|
|
lst.Reverse();
|
|
|
|
|
Int16 newData = BitConverter.ToInt16(lst.ToArray(), 0);
|
|
|
|
|
return newData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 高低位转换(byte[0]byte[1]byte[2]byte[3]->byte[3]byte[2]byte[1]byte[0])
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="a">要进行高低位转换的Int32类型变量</param>
|
|
|
|
|
/// <returns>返回转换后的值</returns>
|
|
|
|
|
public static int Swap(int a)
|
|
|
|
|
{
|
|
|
|
|
byte[] orignalData = BitConverter.GetBytes(a);
|
|
|
|
|
List<byte> lst = new List<byte>();
|
|
|
|
|
for (int i = 0; i < orignalData.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
lst.Add(orignalData[i]);
|
|
|
|
|
}
|
|
|
|
|
lst.Reverse();
|
|
|
|
|
int newData = BitConverter.ToInt32(lst.ToArray(), 0);
|
|
|
|
|
return newData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 解析二进制位
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 解析二进制位
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x">要解析的变量</param>
|
|
|
|
|
/// <param name="len">解析的长度</param>
|
|
|
|
|
/// <returns>返回解析的二进制值数组</returns>
|
|
|
|
|
public static int[] ParseBinaryValue(int x, int len)
|
|
|
|
|
{
|
|
|
|
|
int[] result = new int[len];
|
|
|
|
|
int b = 1;
|
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
|
{
|
|
|
|
|
result[i] = (x & b) == 0 ? 0 : 1;
|
|
|
|
|
b = b << 1;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|