ah! Danke.
Die Typisierung bei IEnumerable ist mir nicht klar.
Ich werde mal var auch mit diesem Link versuchen zu verstehen:
Typbeziehungen in LINQ-Abfragevorgängen (C#)
Hallo,
der Regex "konsumiert" den kompletten string.
Außerdem mußt du die matches in einer Schleife abfragen.
Hier ein funktionierender Vorschlag:
string text = @"asdrer(erer)fasdf<abc>asd(urer)fasdf<ts>adf</ts></abc>";
string ba = @"\((?<inner>[^\)]*)\)";
Match match = Regex.Match(text, ba);
foreach (Match __match in Regex.Matches(text, ba))
{
var __res = __match.Groups["inner"].Value;
}
Noch eine Frage von mir. Wenn ich in der Foreach-Schleife schreibe:
foreach (var __match in Regex.Matches(text, ba))
wird aus der MatchCollection ein Object für var als Typ gesetzt.
Warum diese "Schwäche" bei MatchCollection? Ist das kein IEnumerable? Wieso läuft dann foreach trotzdem so:
foreach (var __match in Regex.Matches(text, ba))
{
var __res = ((Match)__match).Groups["inner"].Value;
}
??
Hallo,
ich sehe die Businesslogik ganz unabhängig vom UI. Du baust Zugriffsmethoden wie: GetAllDivisions und GetDivision (id) AddGroup(division, group) usw.
Diese Businessmethoden greifen dann auf die Datenschicht zu. Dort sind die von dir beschriebenen Objekte definiert.
Und die UI:
Das xaml der UI ist mit Bindings auf das ViewModel verknüpft, welches entsprechend der Controls in der UI verschiedene Properties und Enumerables anbietet. Diese wiederum werden im Getter eine Abfrage der Businesslogik haben. Und im Setter die Methoden der Businesslogik zum Ändern der internen Objekte. Mit PropertyChanged()-Aufrufen, damit auch die anderen Properties im ViewModel aktuell gehalten werden und entsprechend in den Controls angezeigt werden.
Demo's hierfür gibts bestimmt überall. Wenn du fündig wirst kannst du ja mal einen schönen Link posten?
Interessant!
diese Libraries werde ich mir auch mal ansehen.
Mein Vorschlag wäre noch 'PDFCreator' oder ähnliches zu probieren. Hier wird ein Drucker 'simuliert', und als Output PDF geschrieben.
Ein anderer Weg wäre vielleicht über etwas wie das 'TXControl'. Das kann Text laden, pdf exportieren. Kostet aber (viel) Geld. www.textcontrol.com
Mit dem OpenXML SDK kommt ein Code-Generator im sog. ProductivityTool.
Du lädst ein Docx rein und kannst schon auf die einzelnen Parts springen.
Dann Reflect Code und raus kommt ein Progrämmchen, um genau dieses Docx zu erzeugen.
Habe ich mal für ein Bild gemacht:
// Einfügen des Imageparts
ImagePart imagePart1 = mainDocumentPart1.AddNewPart<ImagePart>("image/png", "rId4");
GenerateImagePart1Content(imagePart1);
// Generates content of imagePart1.
private void GenerateImagePart1Content(ImagePart imagePart1)
{
System.IO.Stream data = GetBinaryDataStream(imagePart1Data);
imagePart1.FeedData(data);
data.Close();
}
//...
#region Binary Data
private string imagePart1Data = "iVBORw0KGgoAAAANSUhEUgAAAXgAAABKCAIAAAA... usw "
private System.IO.Stream GetBinaryDataStream(string base64String)
{
return new System.IO.MemoryStream(System.Convert.FromBase64String(base64String));
}
// und jetzt das Aufbauen des XMLs im Document, na ja halt generated...
//...
Drawing drawing1 = new Drawing();
Wp.Inline inline1 = new Wp.Inline(){ DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U };
Wp.Extent extent1 = new Wp.Extent(){ Cx = 3580765L, Cy = 706120L };
Wp.EffectExtent effectExtent1 = new Wp.EffectExtent(){ LeftEdge = 19050L, TopEdge = 0L, RightEdge = 635L, BottomEdge = 0L };
Wp.DocProperties docProperties1 = new Wp.DocProperties(){ Id = (UInt32Value)1U, Name = "Bild 1" };
Wp.NonVisualGraphicFrameDrawingProperties nonVisualGraphicFrameDrawingProperties1 = new Wp.NonVisualGraphicFrameDrawingProperties();
A.GraphicFrameLocks graphicFrameLocks1 = new A.GraphicFrameLocks(){ NoChangeAspect = true };
graphicFrameLocks1.AddNamespaceDeclaration("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
nonVisualGraphicFrameDrawingProperties1.Append(graphicFrameLocks1);
A.Graphic graphic1 = new A.Graphic();
graphic1.AddNamespaceDeclaration("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
A.GraphicData graphicData1 = new A.GraphicData(){ Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" };
Pic.Picture picture1 = new Pic.Picture();
picture1.AddNamespaceDeclaration("pic", "http://schemas.openxmlformats.org/drawingml/2006/picture");
Pic.NonVisualPictureProperties nonVisualPictureProperties1 = new Pic.NonVisualPictureProperties();
Pic.NonVisualDrawingProperties nonVisualDrawingProperties1 = new Pic.NonVisualDrawingProperties(){ Id = (UInt32Value)0U, Name = "Picture 1" };
Pic.NonVisualPictureDrawingProperties nonVisualPictureDrawingProperties1 = new Pic.NonVisualPictureDrawingProperties();
A.PictureLocks pictureLocks1 = new A.PictureLocks(){ NoChangeAspect = true, NoChangeArrowheads = true };
nonVisualPictureDrawingProperties1.Append(pictureLocks1);
nonVisualPictureProperties1.Append(nonVisualDrawingProperties1);
nonVisualPictureProperties1.Append(nonVisualPictureDrawingProperties1);
Pic.BlipFill blipFill1 = new Pic.BlipFill();
A.Blip blip1 = new A.Blip(){ Embed = "rId4", CompressionState = A.BlipCompressionValues.Print };
A.SourceRectangle sourceRectangle1 = new A.SourceRectangle();
A.Stretch stretch1 = new A.Stretch();
A.FillRectangle fillRectangle1 = new A.FillRectangle();
stretch1.Append(fillRectangle1);
blipFill1.Append(blip1);
blipFill1.Append(sourceRectangle1);
blipFill1.Append(stretch1);
Pic.ShapeProperties shapeProperties1 = new Pic.ShapeProperties(){ BlackWhiteMode = A.BlackWhiteModeValues.Auto };
A.Transform2D transform2D1 = new A.Transform2D();
A.Offset offset1 = new A.Offset(){ X = 0L, Y = 0L };
A.Extents extents1 = new A.Extents(){ Cx = 3580765L, Cy = 706120L };
transform2D1.Append(offset1);
transform2D1.Append(extents1);
A.PresetGeometry presetGeometry1 = new A.PresetGeometry(){ Preset = A.ShapeTypeValues.Rectangle };
A.AdjustValueList adjustValueList1 = new A.AdjustValueList();
presetGeometry1.Append(adjustValueList1);
A.NoFill noFill1 = new A.NoFill();
A.Outline outline1 = new A.Outline(){ Width = 9525 };
A.NoFill noFill2 = new A.NoFill();
A.Miter miter1 = new A.Miter(){ Limit = 800000 };
A.HeadEnd headEnd1 = new A.HeadEnd();
A.TailEnd tailEnd1 = new A.TailEnd();
outline1.Append(noFill2);
outline1.Append(miter1);
outline1.Append(headEnd1);
outline1.Append(tailEnd1);
shapeProperties1.Append(transform2D1);
shapeProperties1.Append(presetGeometry1);
shapeProperties1.Append(noFill1);
shapeProperties1.Append(outline1);
picture1.Append(nonVisualPictureProperties1);
picture1.Append(blipFill1);
picture1.Append(shapeProperties1);
graphicData1.Append(picture1);
graphic1.Append(graphicData1);
inline1.Append(extent1);
inline1.Append(effectExtent1);
inline1.Append(docProperties1);
inline1.Append(nonVisualGraphicFrameDrawingProperties1);
inline1.Append(graphic1);
drawing1.Append(inline1);
//...
#endregion
Na ja, das Tool ist ein guter Einstieg in OpenXML.
In VSTO 3 (Visual Studio 2008) wirst du ein Projekt für ein Office 2003 - AddIn bauen und per Setup verteilen können. Normalerweise wirst du deinen Programmcode, was Funktionalität angeht größtenteils übernehmen können. Schmerzhaft ist der Deploy. In den FAQ's gibt es Näheres dazu.
ich kenne keine Funktionalität in Linq, die den xPath-Ausdruck zurückliefert.
hier Code, um das vielleicht hinzukriegen:
public static string GetCurrentXPath(this XElement element)
{
var __sb = new StringBuilder();
foreach (var ancestors in element.Ancestors().Reverse())
__sb.Append("/" + ancestors.Name.LocalName);
return __sb.ToString() + "/" + element.Name.LocalName;
}
public static string GetCurrentXPath(this XText text)
{
return text.Parent.GetCurrentXPath() + "/text()";
}
Hallo,
interessante Idee, zu casten. Geht aber nicht, außer du implementierst das als Extension Method oder so.
Die Denkweise ist so:
du holst dir einen Verweis auf das betroffene XElement,
fügst (z.B. davor) ein neues Kommentarelement XComment ein (mit entsprechendem Inhalt)
dann löscht du das betroffene Element
Der neue Dom-Baum sieht wie gewünscht aus...
coole Idee!
die Auto-Breite würde abhängig vom Inhalt eine Spalte definieren. Evtl. kann ich hier dann die Breite (z.B. in twips oder so) auslesen!
Danke.
Danke Tom,
Das wäre eine Lösung. Aber hui, das wäre ja für die Gallerie.
Mit deinem Vorschlag im Hinterkopf habe ich mir jetzt aber noch dieses überlegt:
Bei einem Absatzformat den linken Rand fix setzen und den rechtem Rand solange verkleinern, bis der enthaltene Text umgebrochen wird. Dann wäre die Differenz der Ränder ja die Satzbreite?!
Hallo,
ein Google "excel interop cell format" bringt mich auf die Idee dir diesen Link vorzuschlagen: http://msdn.microsoft.com/de-de/library/microsoft.office.interop.excel.range.numberformat%28office.11%29.aspx
Passt das?
Hallo,
für einen Export von xml nach Word docx müsste ich die "optimale" Breite z.B. einer Tabellenspalte berechnen, anhand des Inhalts. Ist in erster Näherung die Summe der Breite der Zeichen. Damit sieht mein Output aber noch häßlich aus. 🙁
Wenn ich aber jetzt Formatierungen (fett, hochgestellt...) oder Fußnoten oder Aufzählungen und so'n Kack (uups) auch berücksichtigen würde, müsste ich viel Aufwand betreiben?
Gibt es einen easy way? Irgend eine Magie? Kann mir Word sowas berechnen? 🙂
Ich bin unterwegs mit OpenXML mit SDK 2.0
Also, für jeden Schubser in eine richtige Richtung wäre ich dankbar!
aha.
Funktioniert es so? Ohne daß ich das jetzt ausprobiert habe.
using System.Reflection; //wg. den BindingFlags...
//...
object[] arglist = { "MeinMakroName" }; //hier evtuelle Parameter mit angeben
Application.GetType().InvokeMember("Run", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, Application, arglist);
Hallo,
in den FAQ's zu VSTO kannst du mehr Details finden. Ich würde auch auf den Aufwand für den Deploy des AddIns hinweisen.
Ich mache den Aufruf in Word (z.B. eines Makro's RandNummerEinfuegen) so:
private void btnRandnr_Click(object sender, RoutedEventArgs e)
{
Microsoft.Office.Interop.Word.Application word = null;
Microsoft.Office.Interop.Word.Document doc = null;
try
{
word = Globals.ThisAddIn.Application;
doc = word.ActiveDocument;
object missing = Type.Missing;
try
{
word.Run("RandNummerEinfuegen", ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
//Fokus wieder loswerden
doc.ActiveWindow.SetFocus();
word.Activate();
}
catch
{
MessageBox.Show("Bitte ihre Erfassungs-Dot als Word-AddIn verbinden. Nur dann kann auf die Funktionalität zugegriffen werden.");
//Fokus wieder loswerden
doc.ActiveWindow.SetFocus();
word.Activate();
}
}
catch (COMException ex)
{
}
}
Ich hoffe du kannst das in Richtung Outlook umbauen. Im Prinzip beruht das auf Interop- Automation. Die Run Methode ruft per IDispatch- Interface das betreffende VBA- Makro auf. Parameter wären auch möglich. Mit .net 4 können evtl. die Type.Missing "Dummy"- Parameter wegfallen, wenn ein dynamic- Typ verwendet wird. Habe ich noch nicht gemacht.
hm,
ich werde für den Export mir wohl erstmal eine Teilmenge des CALS-Modells vornehmen. wenn eine brauchbare 80%-Methode daraus wird, könnte ich das auch öffentlich machen. Den Import von Word2CALS habe ich jetzt...
Hallo,
ich hatte das Problem, nur für bestimmte Worddokumente eine CustomTaskPane einblenden zu wollen, bzw. beim Schließen des Dokuments auch die zugehörige CTP "deaktivieren" zu müssen, beim nächsten Dokument aber wieder ggf. eine neue anzuzeigen.
Ich ziele jetzt auf eine Auflistung (ich bin jetzt bei VS 2010 und Office 2007) Microsoft.Office.Tools.CustomTaskPaneCollection CustomTaskPanes
in der automatisch generierten Klasse "ThisAddIn" oder wie die AddIn-Klasse mit Startup usw. genannt werden soll. Das ist in VS 2005/Office 2003 glaube ich ähnlich.
auf dieser CustomTaskPaneCollection kann mit Add und Remove ein Contol hinzugefügt oder entfernt werden. Mit dem Visible-Property des Controls könnten solche Fenster auch einfach auf unsichtbar geschaltet werden. ich habe aber jeweils beim Hinzufügen zur Collection noch einen Tag-String des Controls zur Identifikation gesetzt und dann ggf. die CTP-Instanz mit Remove aus der Collection entfernt und damit "sterben" lassen.
hier ein Code-Schnipsel:
if (IsXYZDocument(Doc))
{
//das richtig getaggte AddIn entladen.
var _tmpPanes = CustomTaskPanes.Where(e => e.Title.StartsWith("XYZ AddIn") && ((string) e.Control.Tag) == Doc.Name);
if (_tmpPanes.Count() > 0)
{
var _tmpPane = _tmpPanes.First();
this.CustomTaskPanes.Remove(_tmpPane);
}
}
ist das bei Outlook ähnlich?
Von außerhalb des AddIn-Codes kannst du über Globals.ThisAddIn.CustomTaskPanes auf diese Klasse zugreifen.
Vielleicht ist das ja eine Spur.
Hallo,
also mir hilft das OpenXML SDK 2.0 sehr.
Toll:
Nachteil:
Ich habe bisher nur mit Word gearbeitet. Bei z.B. Excel kann ich nichts dazu sagen.
Dein spezielles Problem Text aus einer Datei an eine Stelle einer anderen Datei zu kopieren würde ich aber "herkömmlich" mit dem Word-Objektmodell aus dem Namespace Word.Interop lösen:
Range setzen, kopieren und an der anderen Stelle einfügen.
http://msdn.microsoft.com/de-de/library/kw65a0we%28VS.80%29.aspx
Hallo,
du findest ein paar Links für das Deployen von VSTO AddIns z.B. hier:
http://fishersystems.blogspot.com/2010/04/how-to-deploy-vsto-word-template.html
Ich habe gestern hier auf eine andere Frage zu VSTO noch was getextet und noch ein paar Links geschickt. Such' doch mal nach.
Hallo,
VSTO ist die Brücke zwischen der managed - Welt und der Office- COM- Welt.
Um eine Action-Pane zu implementieren braucht es nicht viel.
Das Deployen ist krude. Dazu brauchst du ein Setup (Click-Once oder Windows-Installer).
Wenn du dir ein Click-Once Paket erzeugen lässt (auf Projekteigenschaften/Publish), kannst du das auf dem Zielrechner installieren. z.B. per Stick verteilen.
hier ein Einstieg (-> noch unter VS 2008):
http://fishersystems.blogspot.com/2010/04/how-to-deploy-vsto-word-template.html
Oder irgendwelche Webcasts von jens häupel zum Thema...
und hier ein MSDN-Überblick:
http://msdn.microsoft.com/en-us/library/bb772100.aspx
zu bedenken bei dokument-zentrischen Action Panes:
http://msdn.microsoft.com/en-us/library/bb772072.aspx
na ja, viel Spaß dabei.
also irgendwie so bekommst du den Text doch gelöscht?
ActiveWindow.Selection.WholeStory();
ActiveWindow.Selection.Start = 10;
ActiveWindow.Selection.Delete();
Wenn Selection nichts bewirkt, benutze vielleicht Range?
Oder schicke nochmal einen etwas ausführlicheren Codeschnipsel.
hilft es das Add-In für "All Users" zu installieren? Keine Ahnung wie so ein Terminalserver tickt.
http://blogs.msdn.com/b/mshneer/archive/2008/04/24/deploying-your-vsto-add-in-to-all-users-part-iii.aspx
Mit ClickOnce wird das nicht gehen. Du müsstest einen MSI-Installer bauen mit obigen Veränderungen
Hm, ich würde das Excel Sheet als csv speichern und per StreamReader auslesen.
Das ist jetzt nur mein spontaner Gedanke, ohne deinen Code oben richtig gelesen zu haben.
Hallo,
um eine Datenbank in Silverlight anzusprechen brauchst du immer einen WebService. Wegen der Asynchronität der Methodenaufrufe.
Die richtige Technik hierzu wären die RIA Services:
http://www.silverlight.net/getstarted/riaservices/
Hallo,
noch so eine Stolperfalle: <p>bla bla Gmbh & Co bla bla</p>
hab's nicht probiert, aber sollte als Gmbh & Co ausgegeben werden
ebenso, wenn du selber ISO-Entities in dem String verwendest, z.B.
hab's nicht probiert, aber sollte als &nbsp; ausgegeben werden
dieser Weg ist aber sehr steinig! Ich kenne mich besser bei Word (docx) aus. Aber Excel ist derselbe Schmäh:
Du liest direkt die xml-Struktur aus, aber Info's die du benötigst liegen ggf. nicht in dieser einen xml-Datei, sondern werden per ID referenziert. Der Wert liegt dann in einer anderen Datei.
Mit dem Open XML SDK 2.0 for Microsoft Office kannst du hier bequemer arbeiten. Hier wird dir ein richtiges Modell der OpenXML Dateien angeboten mit Datentypen usw.
Kannst du nicht die Start und End Properties der Selection setzen auf den Text, den du loswerden willst? Wenn ich dich recht verstehe, willst du alles, was nach der Fundstelle kommt löschen? Dann setze das End-Property auf das Dokumentende.
Dann die Methode Delete aufrufen und den neuen Text einfügen.
(m)ein komplexes Problem:
eine Generierung von Dokumenten im OpenXML-Format aus xml-Dokumenten heraus. Mir fehlt eine Umsetzung für CALS-Tabellen. Alle anderen Elemente meiner DTD bekomme ich relativ einfach umgesetzt mit Mitteln des OpenXML SKD 2.0
Leider sind CALS-Tabellen so komplex, dass ich mich hier nicht recht ranwage. Nach lauter googeln ist mir schon schwindlig und ich habe noch keinen rechten Lösungsansatz.
Kann sich jemand vorstellen, wie sowas zu implementieren wäre (XSLT ??). Oder kennt jemand ein Tool, welches das automatisiert? Ich kenne den Downcast von infinity loop, aber kann nicht sehen, wie ich das von .net aus automatisiert bekommen könnte.