You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1686 lines
60 KiB
C#

1 year ago
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
}
}