2015-10-26 25 views
1

我試圖從datagridview基於來自用戶的輸入檢索最接近的較低值。從datagridview獲取最接近的較低值

例如,我有數據的這兩行:

dgvKeyFactorTable.Rows.Add(new object[] { 00000m, 1.000m }); 
dgvKeyFactorTable.Rows.Add(new object[] { 150000m, 1.873m }); 
dgvKeyFactorTable.Rows.Add(new object[] { 155000m, 1.938m }); 

如果用戶輸入150000,程序正確引用1.873本聲明:

var _factorKeyVariable = this.dgvKeyFactorTable.Rows.Cast<DataGridViewRow>() 
.Where(r=>(decimal)r.Cells[0].Value == decimal.Parse(txtCoverageA.Text)) 
.Select(r=>(decimal)r.Cells[1].Value) 
.FirstOrDefault(); 

factorKey = _factorKeyVariable; 
lblKeyFactor.Text = factorKey.ToString(); 

不過,我需要能夠讓用戶輸入一個介於此表中值之間的數字 - 例如153500,並讓程序根據公式設置factorKey變量。

爲了使公式的成功,我需要引用最接近的最高數字(155000 & 1.938),我成功地在這裏做的:

var _factorKeyHigh = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>() 
.Where(r => (decimal)r.Cells[0].Value >= decimal.Parse(txtCoverageA.Text)) 
.Select(r => (decimal)r.Cells[1].Value) 
.FirstOrDefault(); 

var _keyFactorCoverageHigh = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>() 
.Where(r => (decimal)r.Cells[0].Value >= decimal.Parse(txtCoverageA.Text)) 
.Select(r => (decimal)r.Cells[0].Value) 
.FirstOrDefault(); 

而且,我還需要捕捉最接近的最低值表格(150000 & 1.873)。這是我遇到麻煩的地方。我使用此代碼試圖這樣做:

var _factorKeyLow = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>() 
.Where(r => (decimal)r.Cells[0].Value <= decimal.Parse(txtCoverageA.Text)) 
.Select(r => (decimal)r.Cells[1].Value) 
.FirstOrDefault(); 

var _keyFactorCoverageLow = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>() 
.Where(r => (decimal)r.Cells[0].Value <= decimal.Parse(txtCoverageA.Text)) 
.Select(r => (decimal)r.Cells[0].Value) 
.FirstOrDefault(); 

然而,這始終是在表中0,1.000返回的最低值。我不知道爲什麼這不起作用,任何人都可以提供一些見解?

回答

1

爲了獲得最高,你可以做到這一點。我簡化了查詢,使其更具可讀性並且更快捷。因爲你不必兩次找到一個項目。

var highfactor= dgvKeyFactorTable.Rows.Cast<DataGridViewRow>() 
    .FirstOrDefault(r => (decimal)r.Cells[0].Value >= decimal.Parse(txtCoverageA.Text)); 

var _keyFactorCoverageHigh = (decimal)highfactor.Cells[0].Value; 
var _factorKeyHigh = (decimal)highfactor.Cells[1].Value; 

但要獲得最低記得00000m, 1.000m也較低,其低於150000m, 1.873m所以FirstOrDefault();會給你這一點,因爲它的第一個發現。請使用LastOrDefault();來獲得最近的物品。

請注意,LastOrDefault也給你第一個發現,但它會搜索從頭到尾。

var lowfactor= dgvKeyFactorTable.Rows.Cast<DataGridViewRow>() 
    .LastOrDefault(r => (decimal)r.Cells[0].Value <= decimal.Parse(txtCoverageA.Text)); 

var _keyFactorCoverageLow = (decimal)lowfactor.Cells[0].Value; 
var _factorKeyLow = (decimal)lowfactor.Cells[1].Value; 
+0

此代碼在'(十進制)r.Cells [0] .Value <= decimal.Parse(txtCoverageA.Text)''拋出空引用異常。 「你調用的對象是空的。」任何時候我改變txtCoverageA字段。 我以前沒有遇到過這個問題。我絕對沒有空值。 –

+1

嘗試'(decimal?)r?.Cells?[0] ?. Value <= decimal.Parse(txtCoverageA.Text)'。某處必須有空值。這將消除它們。任何方式試圖找到它。目前我沒有足夠的信息來幫助。但這應該做的工作@JoeCambareri –

+1

注意,這是不好的,把所有的問號到處都是。只是做測試,看它是否真的有效。逐個刪除問號並嘗試使用最少的問號。 (除了'(decimal?)')。例如,如果它工作,將它從「r?。」中移除。然後從'Cells?'中刪除另一個,等等。直到你得到空例外。這意味着您必須保留剛刪除的問號。 @JoeCambareri –

1

FirstOrDefault返回序列的第一個元素。您正在檢索表格條目序列中的第一個元素,該值小於您的輸入值。

您可以使用LastOrDefault代替小於的情況。這將返回序列的最後一個元素,並且應該是您要查找的內容,只要序列從最小到最大排序。