[C#] Vervangen Excel linefeeds door spatie

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
In een poging om van het gebruik van diverse macro's en veel te veel handmatige aanpassingen in Excel sheets af te komen ben ik bezig om een C# programmaatje te schrijven.
Wat het programma op dit moment doet is alle benodige data uit diverse sheets halen, in een datatable stoppen, diverse bewerkingen uitvoeren op de data en het vervolgens weergeven in een datagridview.

De onderstaande code plaatst de waarde van de Excel cell op de juiste plek in m'n DataRow.
code:
1
2
3
string cellValue;
cellValue = Convert.ToString((excelWorksheet.Cells[rowIndex, colIndex + 1]).Value2);
row[colIndex] = cellValue;


Het kleine detail waar het fout gaat en wat ik maar niet opgelost krijg zijn de Excel linefeeds die in sommige cellen zitten.
Bovenstaande code leest de waarde van deze cellen correct uit maar vervangt de Excel linefeeds voor "", en ik wil deze linefeeds vervangen hebben door " ", een spatie dus.
In de VB macro die aan de Excel sheet hangt vervang ik simpel weg de linefeed door een spatie m.b.v. code die gemaakt is met de Record Macro functie :+

Bovenstaande lijkt de linefeed van Excel (char 10, ALT+010, ALT+Enter, etc.) gewoon compleet te negeren tijdens het omzetten naar de C# string.

Hoe moet ik mijn code aanpassen om te zorgen dat de Excel linefeed wordt vervangen door een spatie voordat deze omgezet wordt naar een string?

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • Coca-Cola
  • Registratie: Maart 2001
  • Laatst online: 03:50
MewBie schreef op woensdag 25 juli 2012 @ 11:16:
De onderstaande code plaatst de waarde van de Excel cell op de juiste plek in m'n DataRow.
code:
1
2
3
string cellValue;
cellValue = Convert.ToString((excelWorksheet.Cells[rowIndex, colIndex + 1]).Value2);
row[colIndex] = cellValue;
Wat zit er in die (excelWorksheet.Cells[rowIndex, colIndex + 1]).Value2 (als je 'm bekijkt in de debugger)? Ik verwacht eigenlijk dat die info er daar al niet meer inzit en dan kijkt het me lastig om het op te lossen in je C# code... Misschien dat er een method is die je toegang geeft tot de raw text met opmaak er in?

Ik keek nog heel even in een oud project van mij, wat staat er in de .Value en .Text van zo'n cell en wat is de .WrapText van zo'n cell?

[ Voor 9% gewijzigd door Coca-Cola op 25-07-2012 12:56 ]


Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Ik heb werkeliijk de ballen verstand van C#, maar is die linefeed niet misschien Carriage Return + Line Feed?
code:
1
cellValue = cellValue.Replace("\r\n", " ");

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
Coca-Cola schreef op woensdag 25 juli 2012 @ 12:47:
[...]


Wat zit er in die (excelWorksheet.Cells[rowIndex, colIndex + 1]).Value2 (als je 'm bekijkt in de debugger)? Ik verwacht eigenlijk dat die info er daar al niet meer inzit en dan kijkt het me lastig om het op te lossen in je C# code... Misschien dat er een method is die je toegang geeft tot de raw text met opmaak er in?

Ik keek nog heel even in een oud project van mij, wat staat er in de .Value en .Text van zo'n cell en wat is de .WrapText van zo'n cell?
Dat ik er niet aan gedacht heb om gewoon even de waarde van cellValue in de gaten te houden :X
Maar goed, ik ben dan ook geen programmeur van beroep :+

Het blijkt dus zo te zijn dat de Excel linefeed wordt ingelezen als een "\n" tijdens het omzetten naar een string.
Het simpelweg invoegen van de volgende regels lost het probleem op.
code:
1
2
3
4
if (cellValue != null)
{
cellValue = cellValue.Replace("\n", " ");
}


De volledige code is dus geworden:
code:
1
2
3
4
5
6
7
string cellValue;
cellValue = Convert.ToString((excelWorksheet.Cells[rowIndex, colIndex + 1]).Value2);
if (cellValue != null)
{
cellValue = cellValue.Replace("\n", " ");
}
row[colIndex] = cellValue;


Mijn dank is groot, ik ben gewoon al anderhalve dag bezig hiermee |:(

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Schijnbaar unescaped die Convert.ToString je Line Feed dan.
http://markyourfootsteps....cape-sequences-in-csharp/

Wellicht kom het niet bij jouw cellteksten voor, maar gebeurt er als in een cel test\ntest staat?
Waarschijnlijk maakt de Convert.ToString er dan test\\ntest van en krijg je als resultaat test\ test
Als dat zo is, denk ik dat je ook vreemde resultaten krijgt met onder andere (dubbele) quotes in je string.

[ Voor 5% gewijzigd door Vaan Banaan op 25-07-2012 14:59 ]

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

Verwijderd

\n wordt escaped naar een newline door de compiler. Als je de string '\n' wilt capturen gebruik je natuurlijk \\n.

Het is immers gewoon C#.

Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Als ik het voorbeeld van MewBie goed begrijp, gebeurt het volgende:
code:
1
2
3
4
5
        A         B   C   D
1  bla bla bla
   regel 2
2  bla bla bla
3
Resultaat van de "\n" replace: "bla bla bla regel 2"

Maar als je nu in A1 het volgende zet:
code:
1
2
3
4
        A                   B   C   D
1  brons\nikkel schroefje
2  bla bla bla
3
Denk ik dat het volgende gebeurt:
• Convert.ToString wordt: "brons\\nikkel schroefje" (escape van de backslash)
• "\n" vervangen door een spatie
• Resultaat: brons\ ikkel schroefje en dat is niet hetzelfde als de waarde in A1

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
Vaan Banaan schreef op woensdag 25 juli 2012 @ 17:04:
Als ik het voorbeeld van MewBie goed begrijp, gebeurt het volgende:
code:
1
2
3
4
5
        A         B   C   D
1  bla bla bla
   regel 2
2  bla bla bla
3
Resultaat van de "\n" replace: "bla bla bla regel 2"
Klopt.
Eerst was het resultaat "bla bla blaregel 2" omdat de "\n" niet weergegeven wordt in de datagridview.
Nu ik de "\n" vervang door " " is het resultaat inderdaad "bla bla bla regel 2", wat dus ook de bedoeling is.
Maar als je nu in A1 het volgende zet:
code:
1
2
3
4
        A                   B   C   D
1  brons\nikkel schroefje
2  bla bla bla
3
Denk ik dat het volgende gebeurt:
• Convert.ToString wordt: "brons\\nikkel schroefje" (escape van de backslash)
• "\n" vervangen door een spatie
• Resultaat: brons\ ikkel schroefje en dat is niet hetzelfde als de waarde in A1
De kans dat dat het resultaat is zit er inderdaad in ja.
Dat zal ik morgen even testen, ik heb nog geen \'s gezien in m'n data, wel worden er /'s gebruikt.
Dat probleem valt denk ik wel op te vangen door eerst "\\" te vervangen door "/" en daarna de "\n" te vervangen.

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 12-09 16:17
Denk ik dat het volgende gebeurt:
• Convert.ToString wordt: "brons\\nikkel schroefje" (escape van de backslash)
• "\n" vervangen door een spatie
• Resultaat: brons\ ikkel schroefje en dat is niet hetzelfde als de waarde in A1
Dat denk je verkeerd. Dat je die \n ziet is alleen maar een manier van de debugger om jouw te zeggen dat er een newline staat. Net zoals de string "\n" in de replace alleen maar een manier is voor jouw om de compiler te vertellen dat er een newline op die plek moet staan. In de daadwerkelijke data staan deze escapes niet. De processor zal het bij het vergelijken een worst zijn of een karakter geldig is in een taal of voor een mens makkelijk leesbaar is, hij kijkt alleen naar de binaire representatie.

Zoals Darkstone al zei: De string "\n" zal zo gauw de code gecompileerd wordt naar het daadwerkelijke newline karater worden omgezet (dus bijvoorbeeld 0x0A in ascii, even unicode en null termination buiten beschouwing latend). En brons\nikkel schroefje blijft gewoon brons\nikkel schroefje maar zo gauw jij met de debugger gaat kijken laat ie inderdaad brons\\nikkel schroefje zien zodat jij als ontwikkelaar kan zien dat het om \ n gaat en niet om een newline.

[ Voor 5% gewijzigd door jmzeeman op 25-07-2012 22:17 ]


Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Ok, duidelijk. Ik ken de taal niet en dacht dat vanwege
Bovenstaande lijkt de linefeed van Excel (char 10, ALT+010, ALT+Enter, etc.) gewoon compleet te negeren tijdens het omzetten naar de C# string.
de Convert.ToString die line feed \n had omgezet naar string "\n"

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Waarom wordt het eigenlijk gekozen voor "\r\n" en niet voor de property "Environment.NewLine" die c# al bezit?

C#:
1
string.Replace(Environment.NewLine, " ");

Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
jmzeeman schreef op woensdag 25 juli 2012 @ 22:13:
[...]

Dat denk je verkeerd. Dat je die \n ziet is alleen maar een manier van de debugger om jouw te zeggen dat er een newline staat. Net zoals de string "\n" in de replace alleen maar een manier is voor jouw om de compiler te vertellen dat er een newline op die plek moet staan. In de daadwerkelijke data staan deze escapes niet. De processor zal het bij het vergelijken een worst zijn of een karakter geldig is in een taal of voor een mens makkelijk leesbaar is, hij kijkt alleen naar de binaire representatie.

Zoals Darkstone al zei: De string "\n" zal zo gauw de code gecompileerd wordt naar het daadwerkelijke newline karater worden omgezet (dus bijvoorbeeld 0x0A in ascii, even unicode en null termination buiten beschouwing latend). En brons\nikkel schroefje blijft gewoon brons\nikkel schroefje maar zo gauw jij met de debugger gaat kijken laat ie inderdaad brons\\nikkel schroefje zien zodat jij als ontwikkelaar kan zien dat het om \ n gaat en niet om een newline.
Ik heb het even geprobeerd en een "\n" in de tekst blijft inderdaad gewoon staan :)
4Real schreef op donderdag 26 juli 2012 @ 08:49:
Waarom wordt het eigenlijk gekozen voor "\r\n" en niet voor de property "Environment.NewLine" die c# al bezit?

C#:
1
string.Replace(Environment.NewLine, " ");
Dat werkt niet in mijn geval, ik denk omdat ik data uit een Excel bestand inlees naar een C# string en er vervolgens een bewerking op uit voer. Op dat moment heb ik dus een Excel NewLine in mijn string staan en geen C# NewLine. Waardoor de Environment.NewLine dus niet gevonden wordt, want verschillend, en er dus niks vervangen wordt.

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • evolution536
  • Registratie: Maart 2009
  • Laatst online: 05-06-2024

evolution536

besh besh

Overigens zou ik om de kleine vergelijkingsfout die eventueel zou kunnen ontstaan te voorkomen je IF statement als volgt maken:

C#:
1
2
3
4
if (!string.IsNullOrEmpty(cellValue))
{
cellValue = cellValue.Replace("\n", " ");
}
Dat werkt niet in mijn geval, ik denk omdat ik data uit een Excel bestand inlees naar een C# string en er vervolgens een bewerking op uit voer. Op dat moment heb ik dus een Excel NewLine in mijn string staan en geen C# NewLine. Waardoor de Environment.NewLine dus niet gevonden wordt, want verschillend, en er dus niks vervangen wordt.
Dit komt omdat Windows in de regel als newline de combinatie "\r\n" gebruikt. Als in Excel bestanden "\n" wordt gebruikt, wat ik me goed kan voorstellen, aangezien het een soort van open xml formaat is, zal de Environment.NewLine niet correct werken.

[ Voor 60% gewijzigd door evolution536 op 26-07-2012 11:16 ]

Pagina: 1