1

ここや他の場所で答えを広範囲に検索しましたが、ほとんど成功していません。

私は OLEDB を使用してスプレッドシートに接続し、データを抽出してデータベースに移植しています。1 つの細かい点を除いて、すべてがかなりスムーズに進んでいます。

Skills という列があり、通常は文字列のエントリを受け取りますが、値が 334423 のような int になることもあります。この値を新しいデータベースに追加しようとすると、エントリは空白になります。

抽出への通常のアプローチ:

    foreach(DataRow dr in dt.Rows)
    {
      /* dealing with other columns */

      sTemp.skill = dr[3].ToString();

      /* more stuff */

    }

しかし、この行の列が int の場合、まったく応答がありません。空の文字列です。例外をスローすることさえありません。これにより、少なくともある程度の方向性が得られます。

私もそれをintとしてキャストしようとしました:

sTemp.skill = (int)dr[3].ToString();

(うまくいきませんでした)

参考までに: 「sTemp」は文字列が関連付けられたオブジェクトで、スキルは文字列です。また、この問題の不思議なほど静かな性質により、何を尋ねるべきかを理解するのが難しくなります。そこにいるOLEDBの専門家は、助けてください!ありがとう

編集:さらに調査した結果、問題は文字列の int への変換/キャストではなく、実際に最初にデータを取得することにあったようです。

数値を持つフィールドのインスタンスでは、(私には思いつかない理由で) 完全に無視されるため、解析するものは何もありません。まさに謎の行動。

OleDbDataAdapter を使用して Excel から int を取得する既知の問題を誰も知らない場合は、お気軽にお答えください...時間を無駄にして申し訳ありません。

編集 #2:更新されたコード ビューは次のとおりです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;

namespace SQEPSkillsImporter
{
    public partial class MainWindow : Form
    {
        string skillsFileName = "";
        List<SkillTemplate> TemplateList = new List<SkillTemplate>();
        public MainWindow()
        {
            InitializeComponent();
        }

        private void skillsFilePathBtn_Click(object sender, EventArgs e)
        {
            this.skillsFileDialog.Filter = "Excel Worksheets|*.xls;*xlsx";
            DialogResult result = skillsFileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                this.skillsFileName = skillsFileDialog.FileName;
                skillsFilePathTxBx.Text = skillsFileName;
            }
        }

        private void readSkillsBtn_Click(object sender, EventArgs e)
        {
            DataTable skillsTable = new DataTable("SkillsResults");

            string connectionString = "Provider=Microsoft.Jet.OleDb.4.0;" +
                " Data Source=" + this.skillsFileName +
                ";Extended Properties=Excel 8.0;";

            using(OleDbConnection Connection = new OleDbConnection(connectionString))
            {
                Connection.Open();

                using(OleDbCommand Command = new OleDbCommand())
                {
                    Command.Connection = Connection;
                    /* The columns I want are in A through D */
                    Command.CommandText = "SELECT * FROM [Skills$A:D]";

                    using (OleDbDataAdapter Adapter = new OleDbDataAdapter())
                    {
                        Adapter.SelectCommand = Command;
                        Adapter.Fill(skillsTable);
                    }
                }
                Connection.Close();
                Connection.Dispose();
            }
            SkillTemplate sTemp = new SkillTemplate();
            foreach (DataRow dr in skillsTable.Rows)
            {
                /* most sGroup, group and heading columns are blank, so remain the same unless changed, meaning the name wont be null */
                if(dr[0].ToString() != "")
                    sTemp.SuperGroup = dr[0].ToString();
                if (dr[1].ToString() != "")
                    sTemp.Group = dr[1].ToString();
                if (dr[2].ToString() != "")
                    sTemp.Heading = dr[2].ToString();
                if (dr[3].ToString() != "")
                    sTemp.Skill = dr[3].ToString();

                /* VERY rough test textbox to verify that my output is correct before sending to DB */
                this.skillsDumpTxBx.Text += sTemp.SuperGroup + " /// " + sTemp.Group + " /// " + sTemp.Heading + " /// " + sTemp.Skill + System.Environment.NewLine;
            }
        }
    }

    public class SkillTemplate
    {
        public string SuperGroup { get; set; }
        public string Group { get; set; }
        public string Heading { get; set; }
        public string Skill { get; set; }
    }
}
4

2 に答える 2

1
sTemp.skill = Convert.ToInt32(dr[3].ToString());

または、このメソッドを使用して任意の型に変換します。

/// <summary>
/// Safe converting to any type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">Value to convert</param>
/// <param name="defaultValue">Default value, sets type of return value</param>
/// <returns>Converted value or defaul when error</returns>
public static T safeConvert<T>(object value, T defaultValue)
{
    try
    {
        return value == null ? default(T) : 
            (T)Convert.ChangeType( value, Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T) );
    }
    catch
    {
        return defaultValue;
    }
}

利用方法:

sTemp.skill = safeConvert(dr[3],0);
// or
String s = safeConvert(obj, string.Empty);
于 2012-12-13T16:12:34.503 に答える
0

dr[3].ToString() が空白を返す場合、DBNull または空白文字列が含まれている可能性があります。クエリをチェックして、4 番目の列 (ゼロベースのインデックス 3) が有効な値を返していることを確認しましたか?

于 2012-12-13T16:27:16.000 に答える