diff --git a/Include/nmNum/nmSubWxs/nmWxIncludeOtherWells.h b/Include/nmNum/nmSubWxs/nmWxIncludeOtherWells.h index 28cf3d4..a00a9bf 100644 --- a/Include/nmNum/nmSubWxs/nmWxIncludeOtherWells.h +++ b/Include/nmNum/nmSubWxs/nmWxIncludeOtherWells.h @@ -52,12 +52,28 @@ struct WellDataRow { { } - /** @brief 至少选择一个产量相时,该井才可作为主动井提交。 */ + /** @brief 当前记录至少有一个已启用的非零产量相时,才可作为主动井提交。 */ bool canCalculate() const { - return m_bCanCalculate && !m_sWellCode.isEmpty() && - !m_sFlowGaugeCode.isEmpty() && - (m_bUseOilRate || m_bUseGasRate || m_bUseWaterRate) && - m_nFlowSegmentIndex > 0; + if(!m_bCanCalculate || m_sWellCode.isEmpty() || + m_sFlowGaugeCode.isEmpty() || m_nFlowSegmentIndex < 1) { + return false; + } + const nmFlowGaugeRecord* pRecord = nullptr; + int nMatchCount = 0; + for(int nIndex = 0; nIndex < m_vecFlowRecords.size(); ++nIndex) { + if(m_vecFlowRecords[nIndex].sGaugeCode == m_sFlowGaugeCode) { + pRecord = &m_vecFlowRecords[nIndex]; + ++nMatchCount; + } + } + return nMatchCount == 1 && pRecord != nullptr && + pRecord->eStatus == NM_GaugeRecord_Usable && + ((m_bUseOilRate && + nmHasNonZeroFlowRate(pRecord->vecOilPoints)) || + (m_bUseGasRate && + nmHasNonZeroFlowRate(pRecord->vecGasPoints)) || + (m_bUseWaterRate && + nmHasNonZeroFlowRate(pRecord->vecWaterPoints))); } }; diff --git a/Src/nmNum/nmData/nmDataAnalyzeManager.cpp b/Src/nmNum/nmData/nmDataAnalyzeManager.cpp index 70c0318..cef769f 100644 --- a/Src/nmNum/nmData/nmDataAnalyzeManager.cpp +++ b/Src/nmNum/nmData/nmDataAnalyzeManager.cpp @@ -309,6 +309,7 @@ static bool applyCurrentMultiPhaseFlowData( return false; } + nmFlowGaugeRecord* pMatchedRecord = nullptr; for(int nRecordIndex = 0; nRecordIndex < vecRecords.size(); ++nRecordIndex) { @@ -316,30 +317,37 @@ static bool applyCurrentMultiPhaseFlowData( if(oRecord.sGaugeCode != sFlowGaugeCode) { continue; } - - oRecord.vecOilPoints.clear(); - oRecord.vecGasPoints.clear(); - oRecord.vecWaterPoints.clear(); - oRecord.vecOilPoints.reserve(nPointCount); - oRecord.vecGasPoints.reserve(nPointCount); - oRecord.vecWaterPoints.reserve(nPointCount); - for(int nPointIndex = 0; - nPointIndex < nPointCount; - ++nPointIndex) { - const double dTime = vvecMultiPhaseData[0][nPointIndex]; - oRecord.vecOilPoints.append(QPointF( - dTime, vvecMultiPhaseData[1][nPointIndex])); - oRecord.vecGasPoints.append(QPointF( - dTime, vvecMultiPhaseData[2][nPointIndex])); - oRecord.vecWaterPoints.append(QPointF( - dTime, vvecMultiPhaseData[3][nPointIndex])); - } - oRecord.bMultiPhase = true; - oRecord.eStatus = NM_GaugeRecord_Usable; - oRecord.nIndexF = nIndexF; - return true; + if(pMatchedRecord != nullptr) { + return false; + } + pMatchedRecord = &oRecord; } - return false; + if(pMatchedRecord == nullptr || + pMatchedRecord->eStatus == NM_GaugeRecord_InvalidIdentity) { + return false; + } + + pMatchedRecord->vecOilPoints.clear(); + pMatchedRecord->vecGasPoints.clear(); + pMatchedRecord->vecWaterPoints.clear(); + pMatchedRecord->vecOilPoints.reserve(nPointCount); + pMatchedRecord->vecGasPoints.reserve(nPointCount); + pMatchedRecord->vecWaterPoints.reserve(nPointCount); + for(int nPointIndex = 0; + nPointIndex < nPointCount; + ++nPointIndex) { + const double dTime = vvecMultiPhaseData[0][nPointIndex]; + pMatchedRecord->vecOilPoints.append(QPointF( + dTime, vvecMultiPhaseData[1][nPointIndex])); + pMatchedRecord->vecGasPoints.append(QPointF( + dTime, vvecMultiPhaseData[2][nPointIndex])); + pMatchedRecord->vecWaterPoints.append(QPointF( + dTime, vvecMultiPhaseData[3][nPointIndex])); + } + pMatchedRecord->bMultiPhase = true; + pMatchedRecord->eStatus = NM_GaugeRecord_Usable; + pMatchedRecord->nIndexF = nIndexF; + return true; } // 单相流量记录:只解析主块,并按井别把数据归入油、气或水相;忽略可能残留的 Ex2/Ex3。 diff --git a/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp b/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp index fc956e8..88199fe 100644 --- a/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp +++ b/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp @@ -80,6 +80,29 @@ const nmFlowGaugeRecord* findFlowRecord( return nullptr; } +// 保留配置只要求 Code 唯一且记录可解析,不要求记录中存在非零产量。 +const nmFlowGaugeRecord* findUniqueUsableFlowRecord( + const QVector& vecRecords, + const QString& sGaugeCode) +{ + if(sGaugeCode.isEmpty()) { + return nullptr; + } + const nmFlowGaugeRecord* pMatchedRecord = nullptr; + for(int nIndex = 0; nIndex < vecRecords.size(); ++nIndex) { + if(vecRecords[nIndex].sGaugeCode != sGaugeCode) { + continue; + } + if(pMatchedRecord != nullptr) { + return nullptr; + } + pMatchedRecord = &vecRecords[nIndex]; + } + return pMatchedRecord != nullptr && + pMatchedRecord->eStatus == NM_GaugeRecord_Usable + ? pMatchedRecord : nullptr; +} + nmFlowGaugeRecord* findMutableFlowRecord( QVector& vecRecords, const QString& sGaugeCode) @@ -398,10 +421,13 @@ void nmWxIncludeOtherWells::setupTable() const bool bHadRequestedPhase = oWellRow.m_bUseOilRate || oWellRow.m_bUseGasRate || oWellRow.m_bUseWaterRate; + const bool bHadValidFlowSelection = findUniqueUsableFlowRecord( + oWellRow.m_vecFlowRecords, + oWellRow.m_sFlowGaugeCode) != nullptr; normalizeFlowSelection(oWellRow); // 新井默认启用三相;若框架当前选择失效,回退到第一条有产量记录。 // 用户已明确把三相都设为“无”时不自动恢复。 - if(!oWellRow.canCalculate() && bHadRequestedPhase) { + if(!bHadValidFlowSelection && bHadRequestedPhase) { for(int nRecordIndex = 0; nRecordIndex < oWellRow.m_vecFlowRecords.size(); ++nRecordIndex) { @@ -574,9 +600,9 @@ void nmWxIncludeOtherWells::addWellDataToTable( void nmWxIncludeOtherWells::normalizeFlowSelection(WellDataRow& data) const { - const nmFlowGaugeRecord* pRecord = findFlowRecord( + const nmFlowGaugeRecord* pRecord = findUniqueUsableFlowRecord( data.m_vecFlowRecords, data.m_sFlowGaugeCode); - if(pRecord == nullptr || !nmIsSelectableFlowRecord(*pRecord)) { + if(pRecord == nullptr) { data.m_sFlowGaugeCode.clear(); data.m_bUseOilRate = false; data.m_bUseGasRate = false; @@ -594,11 +620,12 @@ void nmWxIncludeOtherWells::normalizeFlowSelection(WellDataRow& data) const const int nSegmentCount = flowRecordSegmentCount(*pRecord); if(nSegmentCount <= 0) { - data.m_sFlowGaugeCode.clear(); - data.m_bUseOilRate = false; - data.m_bUseGasRate = false; - data.m_bUseWaterRate = false; data.m_nFlowSegmentIndex = 0; + nmFlowGaugeRecord* pMutableRecord = findMutableFlowRecord( + data.m_vecFlowRecords, data.m_sFlowGaugeCode); + if(pMutableRecord != nullptr) { + pMutableRecord->nIndexF = 0; + } return; } if(data.m_nFlowSegmentIndex < 1 || @@ -711,7 +738,7 @@ void nmWxIncludeOtherWells::populateFlowSegmentCombo( } const bool bSignalsWereBlocked = pComboBox->blockSignals(true); pComboBox->clear(); - const nmFlowGaugeRecord* pRecord = findFlowRecord( + const nmFlowGaugeRecord* pRecord = findUniqueUsableFlowRecord( data.m_vecFlowRecords, data.m_sFlowGaugeCode); const int nSegmentCount = pRecord == nullptr ? 0 : flowRecordSegmentCount(*pRecord);