2017-02-15 89 views
0

我有一个工作表,我在那里添加500个超链接,这个过程大概需要90秒才能完成。我知道部分原因是因为被迫使用Microsoft Interop Excel,部分原因是被迫使用for loop,但必须有一种更快/更高效的方式来实现此目标。这是我目前的语法优化添加超链接语法

public static void AddThatHyper() 
{ 
    long lr, i; 
    string cellVal; 
    WS = xlApp.ActiveWorkbook.ActiveSheet; 
    lr = WS.Cells[WS.Rows.Count, 2].End(Excel.XlDirection.xlUp).Row; 
    for (i = 2; i <= lr; i++) 
    { 
     Object Anchor = WS.Cells[i, 9]; 
     Object TextToDisplay = Convert.ToString(WS.Cells[i, 9]); 
     cellVal = WS.Cells[i, 1].Value; 
     cellVal = cellVal.Substring(0, Math.Min(28, cellVal.Length)); 
     rangeToHoldHyperlink = WS.Range["I" + i]; 

     if (cellVal.Contains("&") || 
      cellVal.Contains(",") || 
      cellVal.Contains("-") || 
      cellVal.Contains(".") 
      ) 
     { 
      xlApp.ActiveSheet.Hyperlinks.Add(Anchor, "", "'" + "CR " + cellVal + "'!A1", "", TextToDisplay); 
     } 
     if (cellVal.Contains("'")) 
     { 
      cellVal = cellVal.Replace("'", "''"); 
      xlApp.ActiveSheet.Hyperlinks.Add(Anchor, "", "'" + "CR " + cellVal + "'!A1", "", TextToDisplay); 
     } 
     else 
     { 
      xlApp.ActiveSheet.Hyperlinks.Add(Anchor, "", "'" + "FR " + cellVal + "'!A1", "", TextToDisplay); 
     } 
    } 
} 

在这里可以做些什么来优化这个语法并使它在更快的时间框架内完成?

+0

问题是,您正试图单独读取和写入单元格。减少执行时间的最佳方法是将所有值作为范围读取并将它们存储在数组中。之后,您可以操作此设置,然后设置整个范围的值。这样可以减少程序所需的COM调用量。看看这个问题:http://stackoverflow.com/questions/6846958/optimized-way-of-adding-multiple-hyperlinks-in-excel-file-with-c-sharp?rq=1。 – Seunhaab

+0

@Seunhaab - 该选项可能有效,但我不清楚如何实现此目的。你能提供示例语法吗?这些答案的URL设置与我的不同,因为我有3种可能的URL应该如何的条件。 –

回答

0

请注意,此代码未经测试。这是一个基于我之前制作的程序的例子。您可能必须进行一些手动调试才能查看值是否正确提取/转换。

public static void AddThatHyper() 
{ 
    long lr, i; 
    string cellVal; 
    WS = xlApp.ActiveWorkbook.ActiveSheet; 
    lr = WS.Cells[WS.Rows.Count, 2].End(Excel.XlDirection.xlUp).Row; 
    string prefix = "";  

    string topCell = "I" + 2; 
    string bottomCell = "I" + lr; 

    //get_Range returns object array 
    Range range = ws.get_Range(topCell, bottomCell); 

    object[,] rangeValues = new object[lr - 2, 1]; 
    string[,] rangeStringValues = new string[lr - 2, 1]; 
    rangeValues = range.Cells.Formula; 

    //turn object array into string array 
    //should contain strings like "=hyperlink(url, text)" 
    for (int i = 0; i < rangeValues.GetLength(0); i++) 
    { 
     rangeStringValues[i, 0] = rangeValues[i, 0]?.ToString() ?? ""; 
    } 

    //edit hyperlinks 
    for (int i = 0; i < rangeStringValues.GetLength(0); i++) 
    { 
     prefix = "FR" 
     string hyperlink = rangeStringValues[i, 0]; 
     MatchCollection fields = Regex.Matches(hyperlink, @"("[A-Za-z0-9\.]*")"); 
     string url = fields[0]?.ToString() ?? ""; 
     string text = fields[1]?.ToString() ?? ""; 

     if (Regex.IsMatch(url, @"[&,\-\.]")) 
      prefix = "CR"; 
     else if (url.Contains("'")) 
     { 
      prefix = "CR" 
      url.Replace("'", "''"); 
     } 
     string formattedUrl = "'" + prefix + url + "'!A1"; 
     rangeStringValues[i, 0]= $"=HYPERLINK(""{formattedUrl }"", ""{text}"")"; 

    } 
    range.set_Value(value: values); 
    range.Formula = range.Value; 
}