programing

OleDB 및 Excel 혼합 데이터 유형: 데이터 누락

lastcode 2023. 4. 22. 09:31
반응형

OleDB 및 Excel 혼합 데이터 유형: 데이터 누락

엑셀을 사용하다Excel 시트의 특정 컬럼을 제외하고 모든 것이 정상입니다.'이라는 은 '아이디'와 같은 .########## ★★★★★★★★★★★★★★★★★」n#########.

OleDB가 데이터 세트/데이터베이스로 읽어 자동으로 처리하도록 시도했지만 '제품'에 있는 모든 값이아이디 라이크n######,,,, 무및및및및및및 다다다다다다다데이터레이더를 사용하여 각 행을 루프하여 수동으로 DataTable을 생성해 봤지만 결과는 똑같았습니다.

코드는 다음과 같습니다.

// add the column names manually to the datatable as column_1, column_2, ...
for (colnum = 0; colnum < num_columns; colnum ++){
  ds.Tables["products"].Columns.Add("column_" +colnum , System.Type.GetType("System.String")); 
}
while(myDataReader.Read()){
  // loop through each excel row adding a new respective datarow to my datatable 
  DataRow a_row = ds.Tables["products"].NewRow();
  for (col = 0; col < num_columns; col ++){
    try {  a_row[col] = rdr.GetString(col);  }
    catch {  a_row[col] = rdr.GetValue(col).ToString(); }
  }
  ds.Tables["products"].Rows.Add(a_row);
}

수 이해가 안 돼요n######떻게게 해???

.4. 파일을.Net 4.0을 사용하고 Excel 파일을 읽었을 때 비슷한 문제가 있었습니다.OleDbDataAdapter MS 의 " 、 " 、 " 부 、 " " Excel " ID " ( PartMS Excel " ID " ) ( 아이디 'Text'는 'Text'는 'Text'입니다.

내가 봤을 때 ADO야.NET은 열의 대부분의 값을 기반으로 데이터 유형을 선택합니다(숫자 데이터 유형과 동점이 있음). 즉, 대부분의 부품이샘플 세트의 ID는 숫자, ADO입니다.NET은 컬럼을 수치로 선언합니다.따라서 ADO.Net은 각 셀을 번호로 캐스팅하려고 시도하지만 "텍스트" 부품에서는 실패합니다.ID 값 및 "텍스트" 부품 가져오기 안 함아이디

은 ★★★★★★★★★★★★★★★★★★★★★★★★.OleDbConnection하여 " " " 를 사용합니다.Extended Properties=IMEX=1;HDR=NO이것은 Import이며 테이블에는 헤더가 포함되지 않음을 나타냅니다.Excel 파일에는 헤더 행이 있으므로 이 경우 ado.net에 해당 행을 사용하지 않도록 하십시오.그런 다음 코드 뒷부분에서 데이터 집합에서 헤더 행을 제거하고 해당 열에 대한 혼합 데이터 유형을 표시합니다.

string sql = "SELECT F1, F2, F3, F4, F5 FROM [sheet1$] WHERE F1 IS NOT NULL";

OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + PrmPathExcelFile + @";Extended Properties=""Excel 8.0;IMEX=1;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text""");

OleDbCommand cmd = new OleDbCommand(sql, connection);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);

DataSet ds = new DataSet();
ds.Tables.Add("xlsImport", "Excel");
da.Fill(ds, "xlsImport");

// Remove the first row (header row)
DataRow rowDel = ds.Tables["xlsImport"].Rows[0];
ds.Tables["xlsImport"].Rows.Remove(rowDel);

ds.Tables["xlsImport"].Columns[0].ColumnName = "LocationID";
ds.Tables["xlsImport"].Columns[1].ColumnName = "PartID";
ds.Tables["xlsImport"].Columns[2].ColumnName = "Qty";
ds.Tables["xlsImport"].Columns[3].ColumnName = "UserNotes";
ds.Tables["xlsImport"].Columns[4].ColumnName = "UserID";

connection.Close(); 

// 이제 LINQ를 사용하여 필드를 검색할 수 있습니다.

    var data = ds.Tables["xlsImport"].AsEnumerable();
    var query = data.Where(x => x.Field<string>("LocationID") == "COOKCOUNTY").Select(x =>
                new Contact
                {
                    LocationID= x.Field<string>("LocationID"),
                    PartID = x.Field<string>("PartID"),
                    Quantity = x.Field<string>("Qty"),
                    Notes = x.Field<string>("UserNotes"),
                    UserID = x.Field<string>("UserID")
                });

가 찾은 여러 에서는 '더하다'를 '더하다'는을 하고 있습니다.IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text[확장 속성(Extended Properties)]를 선택합니다.Brian Wells가 위에 나타낸 것처럼 연결 문자열의 Extended Properties에 "HDR=NO"를 추가하여 혼합 유형을 가져올 수 있도록 하여 이 문제를 해결했습니다.

그런 다음 일반 코드를 추가하여 첫 번째 데이터 행의 이름을 따고 첫 번째 행을 삭제했습니다.

    public static DataTable ImportMyDataTableFromExcel(string filePath)
    {
        DataTable dt = new DataTable();

        string fullPath = Path.GetFullPath(filePath);

        string connString =
           "Provider=Microsoft.Jet.OLEDB.4.0;" +
           "Data Source=\"" + fullPath + "\";" +
           "Extended Properties=\"Excel 8.0;HDR=No;IMEX=1;\"";

        string sql = @"SELECT * FROM [sheet1$]";

        using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, connString))
        {
            dataAdapter.Fill(dt);
        }

        dt = BuildHeadersFromFirstRowThenRemoveFirstRow(dt);

        return dt;
    }

    private static DataTable BuildHeadersFromFirstRowThenRemoveFirstRow(DataTable dt)
    {
        DataRow firstRow = dt.Rows[0];

        for (int i = 0; i < dt.Columns.Count; i++)
        {
            if(!string.IsNullOrWhiteSpace(firstRow[i].ToString())) // handle empty cell
              dt.Columns[i].ColumnName = firstRow[i].ToString().Trim();
        }

        dt.Rows.RemoveAt(0);

        return dt;
    }

문제 없습니다.sh4. 혼합형 문제에 도움이 되서 다행입니다.

Date Time 칼럼은 완전히 다른 동물로 기억하는데 과거에 슬픔에 빠졌던...우리는 OleDbDataAdapter가 때때로 날짜를 이중 데이터 유형으로 변환하는 하나의 Excel 파일을 가지고 있습니다(확실히 Excel은 날짜를 이중으로 저장하며, 이는 1900년 1월 0일 이후 경과한 일수를 인코딩합니다).

회피책은 다음과 같습니다.

OleDbConnection mobjExcelConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtExcelFile.Text + @";Extended Properties=""Excel 8.0;IMEX=1;HDR=Yes;""");

OleDbDataAdapter mobjExcelDataAdapter = new OleDbDataAdapter("Select * from [" + txtSheet.Text + "$] where [Supplier ID] <> '' ", mobjExcelConn);


DateTime dtShipStatus = DateTime.MinValue;
shipStatusOrig = excelRow["Est Ship Date"].ToString(); // excelRow is DataRow in the DataSet via the OleDbDataAdapter             

if (shipStatusOrig != string.Empty)
{
    // Date may be read in via oledb adapter as a double
    if (IsNumeric(shipStatusOrig))
    {
        double d = Convert.ToDouble(shipStatusOrig);
        dtShipStatus = DateTime.FromOADate(d);

        if (DateTime.TryParse(dtShipStatus.ToString(), out dtShipStatus))
        {
            validDate = true;
            Debug.WriteLine("{0} converted: ", dtShipStatus.ToString("s"));
        }
    }
    else
    {
        if (ValidateShipDate(shipStatusOrig))
        {
            dtShipStatus = DateTime.Parse(shipStatusOrig);
            validDate = true;
            Debug.WriteLine("{0} converted: ", dtShipStatus.ToString("s"));
        }
        else
        {
            validDate = false;
            MessageBox.Show("Invalid date format in the Excel spreadsheet.\nLine # " + progressBar1.Value + ", the 'Ship Status' value '" + shipStatusOrig + "' is invalid.\nDate should be in a valid date time format.\ne.g. M/DD/YY, M.D.Y, YYYY-MM-DD, etc.", "Invaid Ship Status Date");
        }
    }
...
}
        public static Boolean IsNumeric (Object Expression)
        {
            if(Expression == null || Expression is DateTime)
                return false;

            if(Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
                return true;

            try
            {
                if(Expression is string)
                    Double.Parse(Expression as string);
                else
                   Double.Parse(Expression.ToString());
                return true;
            } catch {} // just dismiss errors but return false

            return false;
        }

        public bool ValidateShipDate(string shipStatus)
        {
            DateTime startDate;
            try
            {
                startDate = DateTime.Parse(shipStatus);
                return true;
            }
            catch
            {
                return false;
            }
        }

혼합 데이터 타입과 엑셀을 처리하는 방법은 두 가지가 있습니다.

방법 1

  • Excel 스프레드시트를 열고 열 형식을 원하는 형식으로 수동으로 설정합니다.이 경우 '텍스트'입니다.

방법 2

  • "를 추가하는 "해크"있습니다.IMEX=1"을 다음과 같이 연결 문자열에 연결합니다.

    Provider=프로바이더.Jet.OLEDB.4.0;데이터 소스=myfile.xls;확장 속성=Excel 8.0,IMEX=1

  • 이렇게 하면 레지스트리에 설정된 방법에 따라 혼합된 Excel 형식을 처리할 수 있습니다.이것은 사용자가 로컬로 설정할 수 있지만 서버의 경우 이 옵션이 아닐 수 있습니다.

@Brian Wells 고마워요, 당신의 제안은 성공했지만, 완전히...혼합 필드 int-string에 대해 작동했지만 이후 datetime 열이 이상한 문자로 표시되었기 때문에 "hack" 위에 "hack"을 적용했습니다.

1.- 시스템을 실행합니다.Io.파일Excel 파일의 복사본을 복사하여 만듭니다.

2.- 실행 시 Datetime 열 헤더를 프로그램적으로 Datetime 형식으로 수정합니다(예: "01/01/0001").

3.- Excel을 저장한 후 HDR=NO로 쿼리를 수행하는 트릭을 수정된 파일에 적용합니다.

교묘하게, 네, 하지만 효과가 있었고, 합리적으로 빨랐죠. 누군가 이것에 대한 대안이 있다면, 기꺼이 듣겠습니다.

인사말.

경찰입니다. 죄송합니다. 제 모국어가 아닙니다.

바로 가기 --> Excel에 혼합형 열이 있는 경우: 열 Z를 A로 정렬합니다.

여기서 거의 모든 답을 검토했고, 일부는 나에게 효과가 있었고 일부는 그렇지 않았습니다. 그러나 ADO는 내 Excel 파일에 있는 혼합형 컬럼의 데이터를 선택하지 않았기 때문에 어느 쪽도 바람직하지 않았습니다. 수 없이 을 해야 했다.HDR=NOADO가 텍스트와 숫자가 혼합된 스프레드시트 열을 읽게 하면 SQL 문에서 열 헤더를 사용할 수 없게 됩니다.Excel 파일의 열 순서가 변경되면 SQL 문에 오류가 발생하거나 출력이 잘못됩니다.

혼합 데이터 유형 열에서 키는 처음 8개 행입니다. ADO는 첫 번째 8개의 행을 기반으로 열의 데이터 유형을 결정합니다.따라서 확장 파라미터를 사용하여 연결 문자열을 수정하려면 데이터를 읽기 전에 Excel 파일에서 열 Z를 A로 정렬하기만 하면 됩니다.이렇게 하면 위에 있는 행은 텍스트로 선택됩니다.

첫 번째 행이 숫자일 경우(열 형식이 Excel에서 TEXT로 설정되어 있는지 여부에 관계없이), ADO는 해당 열을 숫자 유형으로 결정하므로 아래 텍스트 행을 읽으면 숫자로 캐스팅할 수 없습니다.반대로 열이 텍스트로 결정되면 행 if number가 있으면 텍스트로 캐스팅할 수 있습니다.

언급URL : https://stackoverflow.com/questions/3232281/oledb-mixed-excel-datatypes-missing-data

반응형