2015-10-16 87 views
1

編寫一個C#程序,我試圖找出是否有某個正確的ID(ClVal)。正在使用Interop將數據從Excel電子表格中讀取並傳輸到數據表中。c#高效If-Then塊

Excel電子表格包含一個命名對象列表,它們的所有者是誰,以及它們所有者的ClVal。

因此,讓我們說PeoplePower,INC。(我現場編造的一個名字)擁有三臺電腦。這三臺電腦都應該具有0000_Peop的ClVal。我需要做的是確保如果這些計算機屬於PeoplePower,INC。,那麼他們擁有正確的ClVal。

我的一個限制是我不能簡單地將ClVal的子字符串與所有者名稱進行比較。這是因爲,如果我從ClVal中獲取子字符串「Peop」並在所有者字段中查找它,那麼對於名稱中某處帶有「Peop」的任何內容,它將返回true(存在)。我想限制任何誤報。

要增加另一層複雜性,只有大量機器的所有者纔會獲得自己獨特的ClVals。對於其他人,他們獲得了「其他」的ClVal。但是,有時一家大公司的機器被賦予「其他」ClVal。

基本上有三種情況來,我們需要檢查,從整體的角度:

If the computer has the correct ClVal (e.g a PeoplePower computer has the ClVal "0000_Peop"), we should assign that cell's value to 1. This helps operators identify machines with the correct ID at a glance, and allows us to enumerate correctly identified machines. 

If the computer has an incorrect ClVal (i.e. a PeoplePower computer has the ClVal "Other"), we should assign that cell's value to 0. This helps operators identify "minor errors" - needs to be fixed but it can wait. 

If the computer does not have a ClVal or it has the ClVal of another owner, the cells value should be a -1. This helps operators identify "major errors" that need to be fixed immediately. 

到目前爲止,我還以爲要做到這一點的一種方式,但我想知道是否有任何更好/更高效的選擇。我目前有大約3500行信息​​進行排序,而且這個數字正在穩步上升,所以我需要一個可以處理更多行數的解決方案。

理念:

string ClVal = Convert.ToString(((Excel.Range)excelStuff.xlWorksheet.Cells[rowIndex, 2]).Value2); 
string name = Convert.ToString(((Excel.Range)excelStuff.xlWorksheet.Cells[rowIndex, 5]).Value2); 

if (name.Contains("PeoplePower")) 
{ 
    string ProperClVal = "0000_Peop"; 
    row[4] = testClVal(ClVal, ProperClVal); 
} 
//Repeat with else if for all of the major owners 
else 
{ 
    if (ClVal == "Other") 
    { 
     row[4] = 1; 
    } 
    else 
    { 
     row[4] = -1; 
    } 
} 
while循環

private int testClVal(String reportedClVal, String ProperClVal) 
{ 
    if (reportedClVal == ProperClVal) 
    { 
     return 1; 
    } 
    else if (reportedClVal == "Other") 
    { 
     return 0; 
    } 
    else 
    { 
     return -1; 
    } 
} 

這是功能性的,但它是一堆的if-then語句的,我也沒有得到進入試的

//外如果我的Excel電子表格由於錯誤的數據(這在一些計算機中發生)而變得不正確,那麼就可以使用這種方法。

有沒有更高效/更好/更快的方式來完成這件事?有3800行,它將數據表的加載時間從1.5分鐘增加到2.5-3分鐘。

回答

1

這是您可以用於這類任務的最快算法類別,因爲您的程序需要觸摸每一行。所以你正在考慮不得不優化程序的其他部分或者其他模式。

要使用Complexity Classes(https://en.wikipedia.org/wiki/Complexity_class)的術語,這是一個O(n)任務,這意味着2000條目需要兩倍於1000條目。你想要做的操作是檢查每一個單獨的值,並做出一個決定,它不依賴於(非常)該值有多大或者有多少值。在僞代碼中:

1) for every Row in Sheet 
2)  lookup a fixed number of values 
3)  do a fixed number of comparisons 
4)  assign a result 
5) end loop 

第1行將執行n次。對於循環中的每一次迭代,您都會執行一組持續成本的操作;我們會說成本是1。這意味着總成本/複雜度將是n * 1 = n,這就是爲什麼這是O(n)。

爲了加快速度,我會考慮使用Excel interop之外的東西(它比NPOI https://npoi.codeplex.com/慢)。另請參閱您是否可以重構該問題:也許您並不需要一次計算所有值,但可以「懶惰地加載」它們或以其他方式推遲計算

+0

我會研究它。謝謝你的幫助! –

1

如何

row[4] = ClVal == "0000_Peop" ? 1 : ClVal == "Other" ? 0 : -1 

此外,還有一些文體的事情,我想提一提。

  • 請使用string,不String無處不在。這是C#中公認的慣例。
  • 您的本地變量應該是camelCase,並以小寫字母開頭。例如,ProperClVal對我來說看起來像一個類名。
0

從excel中讀取一個值是真的很慢。您應該一步讀取所有數據,如:

public object[,] GetArray(int topRow, int rows, int columns) 
{ 
    Range c1 = (Range)Worksheet.Cells[topRow + 1, 1]; 
    Range c2 = (Range)Worksheet.Cells[topRow + 1 + rows - 1, columns]; 
    Range range = Worksheet.get_Range(c1, c2); 

    return range.Value; 
}