sourcecode

Excel 범위에 어레이 쓰기

codebag 2023. 4. 13. 20:48
반응형

Excel 범위에 어레이 쓰기

현재 다음 코드를 사용하여 Excel에서 객체 배열에서 범위로 데이터를 쓰려고 합니다.objData는 문자열 배열에 불과합니다.

private object m = System.Type.Missing;
object[] objData = getDataIWantToWrite();

Range rn_Temp;
rn_Temp = (Range)XlApp.get_Range(RangeName, m);
rn_Temp = rn_Temp.get_Resize(objData.GetUpperBound(), 1);
rn_Temp.value2 = objData;

이것은 거의 기능합니다.문제는 범위는 채워지지만 모든 셀이 첫 번째 항목의 값을 얻는다는 것입니다.objData.

그 반대인 셈이죠.

private object m = System.Type.Missing;
object[] objData = new object[x,y]

Range rn_Temp;
rn_Temp = (Range)XlApp.get_Range(RangeName, m);
rn_Temp = rn_Temp.get_Resize(objData.GetUpperBound(), 1);
objData = (object[])rn_Temp.value2;

는 워크시트의 모든 값을 포함하는 배열을 반환하기 때문에 읽기 및 할당이 다른 이유를 모르겠습니다.

이 일을 성공적으로 해낸 사람이 있나요?현재 어레이 셀을 셀 단위로 쓰고 있습니다만, 많은 행(50,000개 이상)에 대응해야 하기 때문에 시간이 많이 걸립니다.

이건 내 방식에서 발췌한 건데, 이건 내 방식에서 발췌한 건데DataTable(the)dtvariable)을 배열에 입력한 후 배열에 씁니다.Range워크시트(wshvar)를 변경할 수도 있습니다.topRow문자열 배열을 배치할 행에 변수를 지정합니다.

object[,] arr = new object[dt.Rows.Count, dt.Columns.Count];
for (int r = 0; r < dt.Rows.Count; r++)
{
    DataRow dr = dt.Rows[r];
    for (int c = 0; c < dt.Columns.Count; c++)
    {
        arr[r, c] = dr[c];
    }
}
Excel.Range c1 = (Excel.Range)wsh.Cells[topRow, 1];
Excel.Range c2 = (Excel.Range)wsh.Cells[topRow + dt.Rows.Count - 1, dt.Columns.Count];
Excel.Range range = wsh.get_Range(c1, c2);
range.Value = arr;

물론 중급자를 사용할 필요는 없습니다.DataTable코드 발췌는 한 번의 호출로 워크시트에 어레이를 쓰는 방법을 보여주는 것입니다.

조언해 주셔서 감사합니다.Value vs Value 2의 논쟁으로 다른 검색 결과를 얻을 수 있었습니다.이것에 의해, 해답이 무엇인지 알 수 있었습니다.참고로 Value 속성은 파라미터화된 속성으로 C#의 접근자를 통해 접근해야 합니다.이것들은 get_Value 및 set_Value라고 불리며 옵션의 열거값을 취합니다.관심있는 사람이 있다면, 이게설명되는군요.

그러나 Value2 속성을 통해 할당하는 것은 가능합니다.이는 상호운용 설명서에서 get_Value 및 set_Value 메서드를 사용하지 않는 것이 좋습니다.이는 제가 이해할 수 없는 이유입니다.

열쇠는 객체 배열의 치수인 것 같습니다.호출이 작동하려면 어레이가 1차원 데이터만 할당하는 경우에도 2차원으로 선언되어야 합니다.

데이터 어레이를 데이터 어레이로 선언했습니다.object[NumberofRows,1]그리고 할당 콜은 성공했습니다.

이 경우 프로그램은 DataGridView를 반환하는 데이터베이스를 쿼리합니다.그리고 그것을 배열에 복사합니다.방금 작성한 어레이의 크기를 가져와 Excel 스프레드시트에 씁니다.이 코드는 약 2초 만에 5000줄 이상의 데이터를 출력합니다.

//private System.Windows.Forms.DataGridView dgvResults;
dgvResults.DataSource = DB.getReport();

Microsoft.Office.Interop.Excel.Application oXL;
Microsoft.Office.Interop.Excel._Workbook oWB;
Microsoft.Office.Interop.Excel._Worksheet oSheet;
try
{
    //Start Excel and get Application object.
    oXL = new Microsoft.Office.Interop.Excel.Application();
    oXL.Visible = true;

    oWB = (Microsoft.Office.Interop.Excel._Workbook)(oXL.Workbooks.Add(""));
    oSheet = (Microsoft.Office.Interop.Excel._Worksheet)oWB.ActiveSheet;

    var dgArray = new object[dgvResults.RowCount, dgvResults.ColumnCount+1];
    foreach (DataGridViewRow i in dgvResults.Rows)
    {
        if (i.IsNewRow) continue;
        foreach (DataGridViewCell j in i.Cells)
        {
            dgArray[j.RowIndex, j.ColumnIndex] = j.Value.ToString();
        }
    }

    Microsoft.Office.Interop.Excel.Range chartRange;

    int rowCount = dgArray.GetLength(0);
    int columnCount = dgArray.GetLength(1);
    chartRange = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[2, 1]; //I have header info on row 1, so start row 2
    chartRange = chartRange.get_Resize(rowCount, columnCount);
    chartRange.set_Value(Microsoft.Office.Interop.Excel.XlRangeValueDataType.xlRangeValueDefault, dgArray);


    oXL.Visible = false;
    oXL.UserControl = false;
    string outputFile = "Output_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx";

    oWB.SaveAs("c:\\temp\\"+outputFile, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing,
        false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    oWB.Close();
}
catch (Exception ex)
{
    //...
}

데이터를 레코드 세트에 넣고 Excel의 Copy From Recordset 메서드를 사용할 수 있습니다.셀 단위로 입력하는 것보다 훨씬 빠릅니다.

코드를 사용하여 데이터 집합에서 레코드 집합을 만들 수 있습니다.이 방법을 사용하는 것이 현재 수행 중인 것보다 빠른지 확인하려면 몇 가지 평가판을 수행해야 합니다.

Excel 시트에 1D 어레이를 쓰고 싶을 때, 1열([n, 1])로 된 2D 어레이를 만들 필요가 없습니다.다음은 코드의 예입니다.

 wSheet.Cells(RowIndex, colIndex).Resize(RowsCount, ).Value = _excel.Application.transpose(My1DArray)

좋은 하루 되세요, 길레스

Excel Utility 클래스를 프로젝트에 추가하여 즐길 수 있습니다.

ExcelUtility.cs 파일 내용:

using System;
using Microsoft.Office.Interop.Excel;

static class ExcelUtility
{
    public static void WriteArray<T>(this _Worksheet sheet, int startRow, int startColumn, T[,] array)
    {
        var row = array.GetLength(0);
        var col = array.GetLength(1);
        Range c1 = (Range) sheet.Cells[startRow, startColumn];
        Range c2 = (Range) sheet.Cells[startRow + row - 1, startColumn + col - 1];
        Range range = sheet.Range[c1, c2];
        range.Value = array;
    }

    public static bool SaveToExcel<T>(T[,] data, string path)
    {
        try
        {
            //Start Excel and get Application object.
            var oXl = new Application {Visible = false};

            //Get a new workbook.
            var oWb = (_Workbook) (oXl.Workbooks.Add(""));
            var oSheet = (_Worksheet) oWb.ActiveSheet;
            //oSheet.WriteArray(1, 1, bufferData1);

            oSheet.WriteArray(1, 1, data);

            oXl.Visible = false;
            oXl.UserControl = false;
            oWb.SaveAs(path, XlFileFormat.xlWorkbookDefault, Type.Missing,
                Type.Missing, false, false, XlSaveAsAccessMode.xlNoChange,
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            oWb.Close(false);
            oXl.Quit();
        }
        catch (Exception e)
        {
            return false;
        }

        return true;
    }
}

사용방법:

var data = new[,]
{
    {11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
    {21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
    {31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
};

ExcelUtility.SaveToExcel(data, "test.xlsx");

안부 전합니다!

어떤 이유에서인지 2차원 배열로 변환하는 것은 나에게 효과가 없었다.그러나 다음과 같은 접근방식을 통해 실현되었습니다.

public void SetRow(Range range, string[] data)
{
    range.get_Resize(1, data.Length).Value2 = data;
}

어레이 정의의 종류가 중요한 것 같습니다.내 경우 17개 항목의 1차원 배열로 2차원 배열로 변환해야 합니다.

열에 대한 정의: object[,] 배열 = 새 개체[17, 1];

행 개체[,] Array= 새 개체[1,17]에 대한 정의;

value2의 코드는 두 경우 모두 동일한 Excel입니다.범위 셀 = activeWorksheet.get_Range(Range); 셀.값 2 = 어레이

LG 게오르크

언급URL : https://stackoverflow.com/questions/536636/write-array-to-excel-range

반응형