53 votes

Écrire un tableau dans une plage Excel

Je suis en train d'essayer d'écrire des données à partir d'un tableau d'objets à une plage dans Excel à l'aide du code suivant, où objData est juste un tableau de chaînes de caractères:

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;

Cette très près des œuvres, le problème étant que la plage se remplit, mais chaque cellule obtient la valeur du premier élément dans l' objData.

L'inverse fonctionne, c'est à dire

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;

serait retourner un tableau contenant toutes les valeurs de la feuille de calcul, donc je ne suis pas sûr pourquoi, la lecture et l'attribution de travailler différemment.

Quelqu'un a déjà fait cela avec succès? Je suis en train d'écrire la matrice de cellule par cellule, mais il doit faire face à beaucoup (>50 000 habitants) de lignes et c'est donc très coûteuse en temps.

98voto

petr k. Points 4890

Ceci est un extrait de method of mine, qui convertit un DataTable (la variable dt) en un tableau, puis l'écrit dans un Range sur une feuille de calcul (wsh var). Vous pouvez également remplacer la variable topRow par la ligne sur laquelle vous souhaitez placer le tableau de chaînes.

         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;
 

Bien sûr, vous n’avez pas besoin d’utiliser un DataTable intermédiaire comme je l’ai fait, l’extrait de code est simplement destiné à montrer comment un tableau peut être écrit dans une feuille de calcul en un seul appel.

11voto

Jon Artus Points 1807

Merci pour les liens les gars - la Valeur de vs Valeur2 argument m'a un autre ensemble de résultats de recherche qui m'ont aidé à réaliser ce qu'est la réponse. Par ailleurs, la Valeur de la propriété est paramétrée de la propriété, qui doit être accessible via un accesseur en C#. Ceux-ci sont appelés get_Value et set_Value, et de prendre une option valeur d'enum. Si quelqu'un est intéressé, qu'il explique bien.

Il est possible de procéder à la cession par la propriété Value2 cependant, ce qui est préférable que l'interopérabilité la documentation recommande à l'encontre de l'utilisation l'utilisation de la get_Value et set_Value méthodes, pour des raisons au-delà de ma compréhension.

La clé semble être la dimension de la matrice des objets. Pour l'appel à travailler le tableau doit être déclaré comme deux dimensions, même si vous avez seulement l'attribution de la dimension des données.

J'ai déclaré mon tableau de données comme un object[NumberofRows,1] et la cession d'appel a travaillé.

4voto

Galwegian Points 29966

Vous pourriez mettre vos données dans un jeu d'enregistrements et de l'utilisation d'Excel Méthode CopyFromRecordset - c'est beaucoup plus rapide que le remplissage de cellule par cellule.

Vous pouvez créer un jeu d'enregistrements à partir d'un dataset à l'aide de ce code. Vous aurez à faire quelques essais pour voir si l'utilisation de cette méthode est plus rapide que ce que vous faites actuellement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X