2017-02-07 1 views
0

많은 부분을 검색하고 내 요구에 적응할 수없는 것을 찾지 못했을 때 물어볼 생각이 들었습니다. 기본적으로 내 전체 범위 (usedRange) 을 통과하는 루프가 필요하고 동일한 행에 3 열 이상의 셀이 비어 있는지 (예 : A10, B10, C10) 확인한 다음 전체 행을 제거해야합니다 . 내 시도C를 사용하여 3 개 이상의 엑셀 범위로 foreach 루프를 만드는 방법 #

하나 다음과 같이

xl.Range emptyCellsDel = MySheet.UsedRange.SpecialCells(xl.XlCellType.xlCellTypeBlanks); 
     xl.Range myRange = emptyCellsDel.Range["A:C"]; 
     const int aCol = 1; const int bCol = 2; const int cCol = 3; 
     for (int i = 1; i < MySheet.UsedRange.Rows.Count; i++) 
     { 
      if ((MySheet.Cells[i, aCol].Value ?? "").ToString() == "" && 
       (MySheet.Cells[i, bCol].Value ?? "").ToString() == "" && 
       (MySheet.Cells[i, cCol].Value ?? "").ToString() == "") 
      { 
       myRange.EntireRow.Delete(); 
      } 
     } 

아이디어/제안의 모든 종류의 평가 멋진 훨씬 것입니다. 미리 감사드립니다.

답변

0

for 루프에서 액세스 한 범위를 수정하지 않으려면 삭제하려는 행을 메모하여 for 루프 외부에서 제거해야합니다.

또한 행을 위로 이동하는 경우 마지막 행을 먼저 제거해야 행 인덱스가 엉망이되지 않습니다. 아래 예제에서 나는 for 루프의 순서를 바꾸고 순서를 적용 할리스트에 행 번호를 저장했다.

xl.Range myRange = emptyCellsDel.Range["A:C"]; 
const int aCol = 1; const int bCol = 2; const int cCol = 3; 
List<int> rowsToDelete = new List<int>(); 
int rowCount = MySheet.UsedRange.Rows.Count 
for (int i = rowCount; i >= 1; i--) 
{ 
    if ((MySheet.Cells[i, aCol].Value2 ?? "").ToString() == "" && 
     (MySheet.Cells[i, bCol].Value2 ?? "").ToString() == "" && 
     (MySheet.Cells[i, cCol].Value2 ?? "").ToString() == "") 
    { 
     rowsToDelete.Add(i); 
    } 
} 
foreach (int row in rowsToDelete) { ((Range)(MySheet.Rows[row])).Delete(XlDirection.xlUp); } 
+0

나는 그것을 시도했지만 어떤 이유로 빈 행을 제거하지 않습니다. –

+0

.Value를 .Value2로 바꾸어보십시오. 셀에 공백이 아닌 기본값이있는 형식을 반환하는 일부 형식 (예 : 날짜/시간)이있을 수 있습니다. – SMStroble

+0

@ JohnG 오른쪽 쓰레기. 나는 그 변화를했다고 맹세한다. 내 대답에 그것을 반영하지 않았을 것이다. 결정된. – SMStroble

0

SmStroble 대답은 다음과 같이 나타냅니다. 엑셀 파일의 TOP에서 시작하여 빈 행을 삭제하면 행을 삭제하고 다른 행을 올리면 색인 생성 문제가 발생하여 루프의 행 색인 생성이 중단됩니다. for 루프 코드에서 해당 변수를 i으로 게시했습니다. 이 방법을 사용하면 빈 행이 누락되어 비어 있지 않은 행이 삭제 될 수 있습니다.

SmStroble의 대답이이 문제를 해결하는 올바른 방법이지만 몇 가지 문제가 있습니다. 첫 번째로 코멘트 된 바와 같이 SmStroble의 해결책은 행을 반복하여 빈 행의 행 인덱스를 찾아 List<int>에 배치하는 것입니다. 여기서 유일한 문제는 foreach 루프를 사용하면 목록에있는 첫 번째 항목부터 시작하여 마지막 항목이 아닌 처음 항목부터 시작한다는 것입니다.

두 번째 문제는 실행 시간입니다. Excel 행을 반복하면 비용이 많이들 수 있습니다. 당신이 for 루프에서 다음 MySheet.UsedRange 줄을 사용하는 경우 :

for (int i = 1; i < MySheet.UsedRange.Rows.Count; i++) {… 

이 줄은 비싸다. 시트에 많은 행이 있으면 상당한 시간이 걸릴 수 있습니다. 단순히 행 수를 보유하고 아래처럼 for 루프에서 사용하는 int 변수하려면이 그러나 간단한 솔루션은 다른 솔루션이 있습니다

int totalRows = MySheet.UsedRange.Rows.Count; 
for (int i = 1; i < totalRows; i++) { 

이 작은 변화는 크게에 따라 실행 속도가 향상됩니다 스프레드 시트의 행 수 730 + 행을 갖는 테스트 시트를 사용하여 for 루프에서 UsedRange을 가지고 2437 밀리 초가 걸렸고 usedRangefor 루프 밖에 있었을 때 1118 밀리 초가 걸렸습니다. 희망이 도움이됩니다.

string filePath = @"C:\YourPathToExcelFile\YourExcelFile.xls"; 
    Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application(); 
    ExcelApp.Visible = true; 
    Workbooks wbs = ExcelApp.Workbooks; 
    Workbook xlWorkbook = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false); 
    Excel._Worksheet MySheet = xlWorkbook.Sheets[1]; 
    const int aCol = 1; 
    const int bCol = 2; 
    const int cCol = 3; 
    List<int> rowsToDelete = new List<int>(); 
    int totalRows = MySheet.UsedRange.Rows.Count; 
    for (int i = totalRows; i > 0; i--) { 
    if ((MySheet.Cells[i, aCol].Value ?? "").ToString() == "" && 
     (MySheet.Cells[i, bCol].Value ?? "").ToString() == "" && 
     (MySheet.Cells[i, cCol].Value ?? "").ToString() == "") { 
     rowsToDelete.Add(i); 
    } 
    } 

    foreach (int row in rowsToDelete) { 
    ((Range)(MySheet.Rows[row])).Delete(XlDirection.xlUp); 
    } 

    xlWorkbook.Save(); 
    xlWorkbook.Close(); 
    ExcelApp.Quit(); 
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook); 
    System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp); 

    Console.WriteLine("Fished processing! Press any key to exit"); 
    Console.ReadKey(); 

EDIT : 상단에 엑셀 파일의 바닥으로부터 루프 위의 코드를 바꾸었다. 이렇게하면 rowsToDelete 목록을 되돌릴 필요가 없습니다.

+0

나는 이것도 잘 해봤지만 제대로 작동하지 않는 것처럼 보입니다. 나는 여기에서 뭔가 잘못하고 있다고 확신하지만, 제대로 작동 할 때까지는 그걸로 바이올린을 치려고합니다. 일반적으로 작동하는 Excel 파일의 행은 약 20,000-30.000입니다. 나는이 작업을 지금까지 만들 수 있었던 방법 (그러나 좀 더 공상적으로 만들려고 노력했다)은 첫 번째 열의 filterin에 의한 것이었고, 때로는 두 번째와 세 번째 열에 공백이있을 수 있음을 알고, 빈 행을 가져 와서 삭제합니다. 그러나 나는 그것에 대해 조금 더 크고 좋게 가고 싶었다. 나는 a.s.a.p.를 게시 할 것이다. 고맙습니다 ! –

관련 문제