如何更可靠,更快速地从C#中的文本表字符串中获取数据

时间:2017-11-16 08:05:32

标签: c# string text clipboard

我将一些数据从SAP GUI屏幕复制到剪贴板。当我将其粘贴到记事本或任何文本编辑器上时,它看起来如下所示。

SAP GUI data

我只想从剪贴板文本表字符串中创建3个字段[创建者,PO日期,文档]。

目前,我正在设法阅读以下数据。

public class DocData
{
    public string CreatedBy { get; set; }
    public string PODate { get; set; }
    public string Document { get; set; }
}

private void GetDocumentData()
{
  var clipboardData = Clipboard.GetText(TextDataFormat.Text);
  List<DocData> docDataList = new List<DocData>();
  for (int separatorCounter = 20; separatorCounter < clipboardData.Count(); separatorCounter = separatorCounter + 13)
  {
   DocData docData = new DocData();
   int index = GetNthIndex(clipboardData, '|', separatorCounter);
   if (index != -1)
   {
    var dataString = clipboardData.Substring(index + 1);
    var sepIndex = dataString.IndexOf('|');
    if (sepIndex != -1)
    {
     docData.CreatedBy = dataString.Substring(0, sepIndex).Trim();
    }
   }
   index = GetNthIndex(clipboardData, '|', separatorCounter + 2);
   if (index != -1)
   {
    var dataString = clipboardData.Substring(index + 1);
    var sepIndex = dataString.IndexOf('|');
    if (sepIndex != -1)
    {
     docData.PODate = dataString.Substring(0, sepIndex).Trim();
    }
   }
   index = GetNthIndex(clipboardData, '|', separatorCounter + 4);
   if (index != -1)
   {
    var dataString = clipboardData.Substring(index + 1);
    var sepIndex = dataString.IndexOf('|');
    if (sepIndex != -1)
    {
     docData.Document = dataString.Substring(0, sepIndex).Trim();
    }
   }
   if (!string.IsNullOrEmpty(docData.Document))
   {
    docDataList.Add(docData);
   }
  }
 }

任何人都可以提出更好的方法来做到这一点而不必过多地操纵字符串。

1 个答案:

答案 0 :(得分:2)

以下是解决问题的方法之一。此示例首先按行拆分文本,然后使用标题查找所需数据的位置,然后遍历行并获取数据。

没有测试过(我可以粘贴文本而不是屏幕截图:)),但它应该可以工作。请查看代码中的注释以获得解释。

如果您还有其他问题,请随时提出。

编辑:添加了缺失的方法

//result list
List<DocData> docDataList = new List<DocData>();

//get clipboard data
string clipboardData = Clipboard.GetText(TextDataFormat.Text);

//split it to array of lines using Environment.NewLine (\r\n);
string[] reportLines = clipboardData.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

if (reportLines.Length < 4) //just an example of checking if there's enough lines
    throw new Exception("wrong number of lines");

//get correct indexes by reading header (positioned on third line, index 2) - in case order changes
int createdIndex = GetColumnIndex(reportLines[2], "Created by");
int PODateIndex = GetColumnIndex(reportLines[2], "PO Date");
int documentIndex = GetColumnIndex(reportLines[2], "Document");

//when you have indexes, loop through remaining lines, starting at fifth (index 4) and get data from that "columns"
for (int i = 4; i<reportLines.Length; i++)
{
    //now split current line by pipes
    string[] lineData = reportLines[i].Split('|');
    //create instance of your class and add data from specific indexes
    DocData docData = new DocData()
    {
        CreatedBy = lineData[createdIndex].Trim(), //also, trim ending spaces,
        PODate = lineData[PODateIndex].Trim(),
        Document = lineData[documentIndex].Trim()
    };
    docDataList.Add(docData);
}

public int GetColumnIndex(string headerLine, string columnName)
{
    List<string> headerNames = headerLine.Split('|').ToList(); //split header columns using pipe |.

    //get index of column by trimming and searching throught header column names
    return headerNames.IndexOf(headerNames.FirstOrDefault(h => h.Trim().Equals(columnName, StringComparison.InvariantCultureIgnoreCase)));

}