Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von Ruben
Thema: [SOLVED]Server - Client Connection über das Internet
Am im Forum: Netzwerktechnologien

Zitat von Kronos_m
Ziemlich gefährlich ;-) aber jetzt weiß ich, dass es wohl nicht an Win 7 oder dem Router liegt, so denke ich zumdinest ?

Ah, okay, das wäre das Stichwort.
Ich habe bislang noch kein Win7 - jetzt würde ich natürlich vorschlagen, dass du den Server auf einen PC mit WinXP laufen lässt (Client ist ja egal) und das testest.
das ist mein einziger Einfall im Moment.

Win7 soll ja den Benutzer (so habe ich mal gehört) vor sich selbst schützen ;)

Thema: TCP Keepalive / Polling
Am im Forum: Netzwerktechnologien

Zitat von Lynix
Mit TcpClient / TcpListener hab ich es bei mir so realisiert, dass alle verbundenen Clients regelmäßig eine "Ping"-Message an den Server schicken, so eine Art Heartbeat quasi. Wenn ein Client nicht mehr "pingt", weiß der Server, dass der Client weg ist.

Nicht besonders schnell bzw. zeitnah, aber was Besseres hab ich nicht gefunden.

Genauso mache ich das bei mir auch. Will nicht sagen, dass es die beste Variante ist, aber es funktioniert. Das läuft bei mir über Timeouts.

Habe das so gelöst:
Der Client ist bei mir passiv und fragt den Server nie, ob er noch da ist, sondern wartet immer auf die Anfrage vom Server, der wissen will, ob der Client noch da ist.
Wenn der Client keine Anfrage mehr vom Server erhält (z.B. 10 Sekunden lang) dann gilt das für den Client als Timeout und die Verbindung zum Server wird getrennt.
Wenn der Client die Verbindung zum Server trennt, schickt dieser ihm einen Byte-Wert, dass er jetzt die Verbindung trennt und schließt den NetworkStream. Der Server erhält die Mitteilung und wirft ihn sozusagen "raus".

Aber habe dabei das Gegen-Problem:
Wenn der Server die Verbundung zum Client beendet, sendet dieser ebenfalls ein Disconnect-ByteWert und schließt dann die Verbindung.
Aber dieser Wert kommt nie beim Client an und der Client beendet mit Timeout.

Ich habe schon Flush() und BinaryWriter-Klasse versucht zu verwenden, aber nichts hat geholfen.

Wie stelle ich sicher, dass die Daten noch beim Client ankommen, bevor der Server dicht macht?

Thema: TCP Server hängt sich auf
Am im Forum: Netzwerktechnologien

Auf keinen Fall so lösen!!! ^^

Zitat von progi123
Danke für den Hinweis. Hab das jetzt so gelöst:


if (tcpClient.Connected)
{
       //....
}
else 
{
       break;
}
Denn ich habe das schon sehr oft durchprobiert.
Selbst wenn der Client auf der anderen Seite Close() gemacht hat, steht bei mit am Server immer noch tcpClient.Connectet == true.

Ich habe das dann so gelöst, dass mein Client einen Byte-Wert schickt und dadurch dem Server signalisiert, dass er jetzt die Verbindung trennt.

Nur habe ich dabei das Problem: Wenn der Server beendet wird, dann empfängt der Client keine Daten. Ich prüfe dazu immer networkStream.DataAvailable...

Thema: [SOLVED]Server - Client Connection über das Internet
Am im Forum: Netzwerktechnologien

Leider weiß ich auf noch immer nicht, warum es zu diesem Fehler kommt.
Aber die Meldung bekomme ich immer, wenn der Server nicht läuft oder der Port falsch ist:


SocketException: Es konnte keine Verbindung hergestellt werden, da der Zielcomputer die Verbindung verweigerte.

Wie man dieses Problem jedoch lösen kann, weiß ich leider nicht genau.
Theoretisch müsste ich dazu sowohl die Firewall-Einstellungen in Windows und die Router-Konfiguration einsehen. Aber das verlange ich nicht ;)

Merkwürdig ist allerdings, dass es über diese Internetseite Open-Ports funktionierte, aber nicht über einen außenstehenden PC.
Zitat von Kronos_m
@Ruben: habe es nun auch mit einem anderen PC getestet, über einen anderen Router. Ohne Erfolg, die Fehlermeldung bleibt die Gleiche.
Hast du dazu TelNet benutzt? (obwohl das wahrscheinlich keinen so großen Unterschied macht, vermute ich)

Thema: Callback in MainThread ausführen
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Stimmt, der MainThread muss die Anforderung irgendwie entgegennehmen.
Denn z.B. in einer normalen Konsolenanwendung gibt es keinen Punkt, an dem der MainThread irgendwelche Anforderungen von anderen Threads annehmen kann, außer es ruft sie ab.

Also gibt es nur zwei Möglichkeiten:
- lösen über Synchronisation, oder
- verzichten, wenn es nicht notwendig ist

Letztlich muss man sich nur fragen warum(?) man das brauch.
Theoretisch kann man dann auch 3 Threads machen:
- einer der die Anforderungen abarbeitet (nehmen wir mal den MAIN)
- einer der den eigentlichen Code ausführt (zwar der Hauptthread, aber nur woanders ausgeführt)
- und einer der den 2. Thread darstellt

beide Threads geben ihre Anforderung an den MAIN-Thread und so wird alles im selben Thread ausgeführt - oder so ähnlich ^^

Thema: Seitenzahlen in Fußzeile einfügen - Word
Am im Forum: Office-Technologien

vielleicht passiert das bei


foreach (Word.Field field in doc.Fields)
                    {
                        field.Update();
                    } 

leider weiß ich nicht was in den Fields so drin steckt, aber eventuell könntest du das im DebugMode prüfen und dann nur die richtigen Felder aktualisieren.

Thema: Callback in MainThread ausführen
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hier eine Idee wie es auf jeden Fall funktioniert - vergleiche mal:

EDIT:
Mist, der Callback ist nicht im MainThread ^^


class MainThreadClass
    {
        public MainThreadClass() { }

        public void DoWork()
        {
            AnotherThread other = new AnotherThread();
            this.methodDelegator = new System.Threading.ThreadStart(other.DoWork);
            this.methodDelegator.BeginInvoke(new AsyncCallback(this.ThreadCallback), null);

            // so kann man das auch machen - ALTERNATIVE
            //System.Threading.ThreadStart d = new System.Threading.ThreadStart(other.DoWork);
            //d.BeginInvoke(new AsyncCallback(this.ThreadCallback), d);


            // ... (belibiger Code) 1. Thread
        }

        private System.Threading.ThreadStart methodDelegator;

        private void ThreadCallback(IAsyncResult result)
        {
            // Callback wird hier ausgeführt, wenn der Thread beendet wurde
            this.methodDelegator.EndInvoke(result);
            
            // so kann man das auch machen - ALTERNATIVE
            // wenn man oben die Alternative genommen hat
            //System.Threading.ThreadStart d = (System.Threading.ThreadStart)result.AsyncState;
            // d.EndInvoke(result);

            // wichtig ist das EndInvoke um den Vorgang abzuschließen
            // auf diese Weise können auch Rückgabewerte angenommen werden
        }
    }

    class AnotherThread
    {
        public AnotherThread() { }

        public void DoWork()
        {
            //... Code vom 2. Thread
        }
    }

Thema: Architektur: Wie Objekte, von denen nicht (gleich) alle Properties benötigt werden, effizient laden?
Am im Forum: Rund um die Programmierung

Zur Eingangsfrage:

Meine Idee wäre die Datensätze seitenweise auszugeben: z.B. nur 10 auf jeder Seite.
Mit "SELECT TOP 10 * FROM table;" kann man die ersten 10 ausgeben, aber ich bin in SQL nicht so bewandert, doch ich denke dass es möglich ist.

Vorteil:
Es werden beim Anzeigen immer nur maximal 10 Datensätze gezeigt (oder ggf. auch gerne mehr), d.h. es werden auch nur immer 10 Datensätze aus der DB geholt. Mit "SELECT COUNT(*) FROM table;" könnte man die gesammtzahl ermitteln und man müsste nur noch 1-10/200 oder 11-20/200 angeben, aber leider weiß ich nicht wie man auf die Position der Datensätze so kommen könnte.

Thema: Add Ins für Excel 2003 in VS 2008 mit C#
Am im Forum: Office-Technologien

Zitat von Sebastian.Lange
Möglicherweise hilft dir dieser Artikel - http://support.microsoft.com/kb/302901
Vielleicht hast du die dort beschriebene Projektvorlage Gemeinsames Add-In nicht (ich hab sie nicht) aber das Addin hast du ja scheinbar eh schon fertig.
IDTExtensibility2-Schnittstelle?
OnConnection/OnDisconnection?

Geht es dabei nicht um Entwicklung von AddIns ohne VSTO?


Dann ist der Link richtig, aber nach dem was morbus85 sagte:
Zitat von morbus85
Durch das Wandern durch viele Seiten hab ich in Erfahrung gebracht, dass es anscheinend unmöglich ist ein eigenes AddIn zu verbreiten ohne ein teures VSTO zu kaufen.
scheint es mir, dass er mit VSTO entwickelt.


Daher meine Frage: Ist der Verweis auf diesen Link die Bestätigung der Aussage von morbus85, dass man VSTO entwickelte AddIns nicht weitergeben kann?


Wenn es doch möglich ist (ohne das auf jedem Rechner das komplette VSTO installiert werden muss) dann bin ich daran äußerst interessiert.

Thema: [SOLVED]Server - Client Connection über das Internet
Am im Forum: Netzwerktechnologien

Hallo Kronos_m,

da der Fehler nur Auftritt, wenn du vom selben PC aus auf dich selbst versuchst zu connecten (über die externe Router-IP) werde ich nur mal vermuten, dass aus irgendeinem Grund solche reflexiven Verbindungen nicht geroutet werden.

Leider weiß ich nicht genau warum, aber wenn du es von einem anderen Computer von außen probieren könntest, der über eine andere Leitung läuft (also nicht denselben Router), dann denke ich mal, dass es funktioniert. Lokal müsstest du dann immer über die Loopback-Adresse (localhost oder 127.0.0.1) testen.

Und von dem was VizOne sagt:
auch möglich, dass es ein IPv4/IPv6-Problem ist

Thema: [erledigt] Größenvergleich zweier Produktversionen
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Alternativ zum entfernen von Zeichen die keine Nummern sind (eigentlich sogar sinnvoller) finde ich persönlich Lamda-Ausdrücke.
Jedenfalls bin ich ein Freund von sowas

z.B. so


string versionsString = "1.24";
string versionsnummer = // ≤= 124
     versionsString.Aggregate<char, string>(
               String.Empty, (s, c) => s += (Char.IsNumber(c) ? c.ToString() : String.Empty));

Das musste ich einfach loswerden


Sonst ist System.Version das wohl beste.

Thema: Herausfinden ob Objekt eine Liste ist
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Noch besser allerdings ist:


public static bool IsEnumerable(object obj)
{
     if(obj == null)
          return false;

     return obj is IEnumerable;
}

Damit deckt man so ziemlich alles ab: List, Array, Dictionary,...
Wenn man wirklich eine List<T> meint, dann hilft auch das so zu machen:


     return obj is IList;

Anschließend muss man nur noch umwandeln und auslesen.
Bei IEnumerable und IList sind die Elemente der Liste (oder was weiß ich) alle als Object gennant - auch hier ggf. casten.

Thema: Serialisierung von Objekten
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Ich habe einmal etwas gebaut. Leider funktioniert nur das Serialisieren.
Völlig unsauber, da viele Festwerte drin sind und nicht alles geprüft wird, aber vielleicht kann jemand daraus eine Idee entwickeln.

Das Problem ist klar:
Beim Deserialisieren weiß der XmlSerializer nicht welchen Typ das Objekt hat.
Deshalb nimmt er den Typ der Eigenschaft und erstellt daraus eine Instanz.
Anschließend versucht er die Daten in das Objekt zu schreiben, aber das schlägt natürlich fehl.


namespace TestProjekt
{
     public class Auto : System.Xml.Serialization.IXmlSerializable
    {
        public Auto() { }

        public Auto(string color, int doors)
        {
            this.Color = color;
            this.Doors = doors;
        }

        public string Color { get; set; }
        public int Doors { get; set; }

        #region IXmlSerializable Member

        public System.Xml.Schema.XmlSchema GetSchema() { return null; }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            Type auto = this.GetType();
            if (reader.Name == "Car") // Name der Eigenschaft in Person
                reader.Read();
            XElement xElement = (XElement)XElement.ReadFrom(reader);
            foreach (System.Reflection.PropertyInfo property in auto.GetProperties())
            {
                bool ok = true;

                foreach (Attribute attr in property.GetCustomAttributes(true))
                {
                    Type attributeType = attr.GetType();
                    if (attributeType.Namespace.Equals("System.Xml.Serialization"))
                    {
                        if (attr is System.Xml.Serialization.XmlIgnoreAttribute)
                        {
                            ok = false;
                            break;
                        }
                    }
                }

                if (!ok || !property.CanRead || !property.CanWrite)
                    continue;

                if (xElement.Name == auto.Name) // beim Deserialisieren immer FALSE
                {
                    if (xElement.Element(property.Name) != null)
                        property.SetValue(this, Convert.ChangeType(xElement.Element(property.Name).Value, property.PropertyType), null);
                }
            }
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            Type auto = this.GetType();
            XElement xElement = new XElement(auto.Name);
            foreach (System.Reflection.PropertyInfo property in auto.GetProperties())
            {
                bool ok = true;

                foreach (Attribute attr in property.GetCustomAttributes(true))
                {
                    Type attributeType = attr.GetType();
                    if (attributeType.Namespace.Equals("System.Xml.Serialization"))
                    {
                        if (attr is System.Xml.Serialization.XmlIgnoreAttribute)
                        {
                            ok = false;
                            break;
                        }
                    }
                }

                if (!ok || !property.CanRead || !property.CanWrite)
                    continue;

                xElement.Add(new XElement(property.Name, property.GetValue(this, null)));
            }
            xElement.WriteTo(writer);
        }
        #endregion
    }
}

Thema: synchron und asynchron schreiben
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Synchron ist...
...wenn man warten muss bis die Datenbankabfrage das Ergebnis liefert und die Anwendung steht
...wenn man den nächsten Schritt erst ausführt, wenn der vorherige beendet wurde
...wenn man erst kleine Dateien lesen kann, wenn die großen eingelesen wurden ;)

Asynchron ist...
...wenn man normal in einer Form arbeiten kann und im Hintergrund die Datenbank abgefragt wird - gerne auch mit warten, aber dann immerhin mit einer Fortschrittsanzeige (ProgressBar)
...wenn man Schritte ausführen kann während der vorherige noch läuft
...wenn man kleine Dateien einlesen kann, während die große Datei eingelesen wird


Das entscheidende Wort ist also "während".

Kurz gesagt:
Bei Synchron mache ich alles in Schritten und logisch festgelegten Abläufen.
Bei Asynchron kann schon das eine fertig sein oder etwas passieren während ich gerade etwas anderes mache.

In der Regel laufen asynchrone Prozesse auf anderen Threads. Also einfach unter den Begriff Threads oder Multithreading schauen.


gruß

Ruben

Thema: Dokumentbezogene Anwendung - Excel 2003 - Bereitstellung für andere PCs
Am im Forum: Office-Technologien

Vielleicht hilft es weiter, aber habe auch schon versucht über folgenden Code das zu lösen, den Code habe ich irgendwo bei der MSDN mal gefunden.


using System;
using Microsoft.VisualStudio.Tools.Applications.Runtime;

namespace ChangeAssemblypathApp
{
    class Program
    {
        [STAThread()]
        static void Main(string[] args)
        {
            ServerDocument sd = null;

            try
            {
                sd = new ServerDocument("documentPath");
                sd.AppManifest.Dependency.AssemblyPath = "assemblyPath";
                sd.Save();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (sd != null)
                    sd.Close();
            }
        }
    }
}

In den Eigenschaften stoße ich auf das Bild im Anhang


Falls es wirklich nicht geht (da VSTO einfach installiert werden muss), kann mir jemand sagen, wie ich am besten meinen Code (der in der ThisWorkbook-Klasse steht) so ändern kann, dass ich das z.B. über eine Anwendung oder ähnliches ausführe? Es soll sich ja nur auf die eine Datei beziehen.

Thema: CS0143 - Erben von einer Basisklasse ohne Konstruktor
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Danke, das über die Reflection zu prüfen, hab ich gar nicht gedacht.
Aber jetzt bin ich dahingehend auch wieder schlauer ;)

Thema: Brauche Hilfe für Überzeugungsarbeit für Dispose u.ä. ...
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hier ist ja auch noch was.
Vor allem der Beitrag von norman_timo:
Dispose implementieren und verwenden (IDisposable)

Damit dürfte die Antwort "perfekt" sein. ;)

Thema: Word: Word-Dokument automatisch in HTML umwandeln
Am im Forum: .NET-Komponenten und C#-Snippets

Zitat von flippy08
Hallo,
ist es möglich den fortschritt einer Konvertierung abzufragen oder in erfahrung zu bringen wann diese beendet ist ?

bei diesem Beispiel könnte das schwierig werden, denn das speichern läuft hier ab:


     // COM-Metadaten von Word.Document ermitteln

    Type wordDocument = document.GetType();

    // HTML erzeugen

    wordDocument.InvokeMember("SaveAs", BindingFlags.IgnoreCase | BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.OptionalParamBinding, null, document, new object[2] {destination,WORD_HTML_FORMAT});

Also in diesem Beispiel denke ich nicht.

Thema: Dokumentbezogene Anwendung - Excel 2003 - Bereitstellung für andere PCs
Am im Forum: Office-Technologien

Leider erfolglos. Fehler:


Microsoft (R) .NET Global Assembly Cache Utility.  Version 1.1.4318.0
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

Failure adding assembly to the cache:   Zugriff verweigert


C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322>

Sieht so aus als könnte ich das mit den eingeschränkten Benutzerrechten nicht machen.
Deshalb hoffe ich auf eine Lösung, die man schnell auf vielen verschiedenen PCs einsetzen kann. Denn wie gesagt: Über Makros könnte ich das auch hinbekommen nur muss ich dann die objektorientierte Ebene verlassen und in VB (vor allem VBA) komme ich nicht ganz so gut zurecht. -.-

Thema: Brauche Hilfe für Überzeugungsarbeit für Dispose u.ä. ...
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Einmal den Tipp von JAck30lena beachten ;)

und

für den Fall einmal hier gucken - unter dem Punkt "IDisposable-Schnittstelle"

Thema: using Gültigkeitsbereich und Dispose() Unterschiede ?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Okay, danke für diese schnelle Antwort und Korrektur.

Ich habe etwas aus meiner unvollständigen Erinnerung geplaudert und es vorher nicht geprüft. Nun bin ich jetzt auch dadurch schlauer geworden ;)

Hoffentlich beanrwortet irgendwann jemand auch meine Eigentliche Frage so schnell ^^

Thema: CS0143 - Erben von einer Basisklasse ohne Konstruktor
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo zusammen,

vor dem Problem stehe ich auch.
Aber alle zu kapseln ist defninitiv nicht die Lösung.

Als Beispiel:
Die Klasse System.Drawing.Bitmap erbt von System.Drawing.Image.
System.Drawing.Image ist eine abstrakte Klasse ohne Konstruktoren.
System.Drawing.Bitmap hat jedoch Konstruktoren.
Wenn ich aber versuche ebenfalls eine Klasse zu schreiben, welche von System.Drawing.Image erbt, dann erhalte ich den Fehler CS0143.


Soll ich etwa glauben, dass es grundsätzlich nicht möglich ist und Microsoft hier bloß die Regeln gebrochen hat? Oder habe ich dabei etwas übersehen?

Thema: using Gültigkeitsbereich und Dispose() Unterschiede ?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

das Problem ist zwar gelöst, aber hier ein kurzer Überblick zu dem Unterschied und wichtigen Punkten bei Using und Dispose() - was ich selber bisher auch festgestellt habe.

Der Vorteil von Dispose
(Das Dispose wirft zum Glück nie eine Exception, egal wie oft es aufgerufen wird.)
- Man kann festlegen, wann genau das Dispose ausgeführt werden soll und die Ressourcen freigegeben werden sollen

Nachteile bei Dispose() - (ohne Vergleich zu Using)
- bei einem Stream kann es vielleicht sein, dass Daten verloren gehen, da man Close verwenden sollte um die Daten in die Datei zu schreiben
(i.d.R. ist Dispose aber immer sinnvoll)


Bei Using ist eines Wichtig
Wenn eine Exception innerhalb des Using-Blocks auftritt, so habe ich festgestellt, wird das Dispose nicht mehr aufgerufen.
Also am besten immer ein Try-Catch-Block im Using machen.
Das im Using verwendete Objekt bitte nicht einem anderen Objekt zuweisen, denn wenn man z.B. ein Bild einer PictureBox zuweist, dann muss unweigerlich ein Fehler auftreten beim Verlassen des Using-Blocks oder das Bild würde sofort wieder verschwinden.

Vorteil bei einem Using-Block
- alle deklarierten Variablen innerhalb des Blocks verfallen, wenn der Using-Block verlassen wird
- durch den Using-Block kann man einen klaren Bereich definieren in dem dieses Objekt ausschließlich verwendet wird
- beim Verlassen des Blocks wird immer die Dispose-Methode aufgerufen


Soweit dazu ;)

Thema: Seitenzahlen in Fußzeile einfügen - Word
Am im Forum: Office-Technologien

Hallo Coder89,

dazu wäre der Code-Ausschnitt am besten, wo die Seitenzahlen in die Fußzeile erstmals eingefügt werden.

Werden eigentlich die Seitenzahlen über eine Word-Feldfunktion aktualisiert oder etwas über den Code?

Feldfunktionen sind da dann sinnvoller, dann gibt es weniger Fehler.
Wie man jedoch eine Feldfunktion in Word an die entsprechende Stelle setzt, weiß ich grad nicht genau aber die Feldfunktion müsste so aussehen:


{ PAGE } von { NUMPAGES }

In C# dann so:


string value = "{ PAGE } von { NUMPAGES }"

Das Wort von ist von mir, aber die geschweiften Klammern stellen die Wordfunktionen dar.

Thema: Interop: Word Dokument feuert Close-Event nicht
Am im Forum: Office-Technologien

Hallo JunkyXL,

bisher hatte ich das Close-Event gar nicht gefunden.
Es ist gut möglich, dass es nicht aufgerufen wird, weil es veraltet ist.
Ich habe mal etwas programmiert, dass die Dateien NACH dem Schließen verschlüsseln soll. Gelöst habe ich das jedoch im DocumentBeforeClose-Event.

Und noch etwas:
Das DocumentBeforClose-Event wird von der Application ausgelöst - vielleicht ist das bei dem Close-Event auch so.
Denn selbst wenn das Event im Document-Objekt ist, kann es dennoch von einem anderen Ort ausgelöst werden bzw. einen anderen Auslöser haben. Dass wäre bei den PIAs möglich, denn bei mir scheinen die unberechenbar ^^.


Hier der Ausschnitt mit dem DocumentBeforeClose-Event:



        /// <summary>
        /// Tritt ein, sobald man ein Dokument schließen möchte - also noch vor dem Speichern.
        /// z.B. durch Klicken auf [X] am Fenster
        /// </summary>
        /// <param name="Doc">Enthält das Dokument, das geschlossen werden soll.</param>
        private void Application_DocumentBeforeClose(Microsoft.Office.Interop.Word.Document Doc, ref bool Cancel)
        {
            if (Doc.Name.ToLower() == "Normal.dot".ToLower())
                return;

            try
            {
                // If-Abfrage
                //    Diese Abfrage prüft, ein Dokument Änderungen aufweist, die noch nicht gespeichert sind.
                //    Ist dies der Fall, wird eine definierte MessageBox aufgerufen und die Eingabe verarbeitet.
                //    >>>  Warum diese Abfrage?
                //    >>>>    Sinn dieser Abfrage ist es zu ermitteln,
                //    >>>>    ob beim Schließen der Speichervorgang abgebrochen wird (z.B. durch Klicken auf Abbrechen).
                if (!Doc.Saved)
                {
                    // Achtung: Diese Methode gibt nur TRUE zurück, wenn man abbrechen will
                    if(DokumentGespeichert(Doc, ref Cancel))
                        return;
                }

                string docFilePath = Path.Combine(Doc.Path, Doc.Name);
                Cancel = true;          

                object SaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges;
                object OrginalFormat = Word.WdOriginalFormat.wdOriginalDocumentFormat;
                Doc.Close(ref SaveChanges, ref OrginalFormat, ref missing);

                // das Document befindet sich am docFilePath und hier sind wir nach dem Close
                // this.DocumentAfterClose(Doc, ref Cancel); wenn man will
            }
            catch (Exception ex)
            {                
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Kann verwendet werden um zu erfragen, ob ein Dokument, dass nicht gespeichert wurde,
        /// gespeichert werden soll.
        /// </summary>
        /// <returns></returns>
        private bool DokumentGespeichert(Microsoft.Office.Interop.Word.Document Doc, ref bool Cancel)
        {
            // MessageBox
            //    Diese MessageBox stellt die Buttons zu verfügung, wie man sie bei der Frage,
            //    zum speichern eines Dokuments bei Word kennt.
            DialogResult result = MessageBox.Show("Möchten Sie die Änderungen in " + Doc.Name + " speichern?",
                                                  "Microsoft Office Word",
                                                  MessageBoxButtons.YesNoCancel,
                                                  MessageBoxIcon.Warning,
                                                  MessageBoxDefaultButton.Button2);

            // Auswerten des Ergenisses der DialogBox bzw. MessageBox
            switch (result)
            {
                case DialogResult.Cancel:
                    Cancel = true;
                    return true;
                case DialogResult.No:
                    break;
                case DialogResult.Yes:
                    Doc.Save();
                    Doc.Saved = true;
                    break;
                default:
                    break;
            }

            return false;
        }

Was hier passiert dürfte klar sein: Beim BeforeClose-Event wird das Speichern verarbeitet und das Dokument geschlossen. Anschließend ist man aber dennoch in der Methode und man kann so alles nach dem Schließen verarbeiten.

Thema: Zwischenablage Excel mit verbundenen Zellen
Am im Forum: Office-Technologien

Hallo Jörg,

das die verbundenen Spalten getrennt werden, liegt möglicherweise daran, das eine Spaltenverbindung eine Formatierung ist und damit möglicherweise anders übertragen wird.

Eine Idee wäre den Umkehrschluss zu nehmen und nachzusehen, was für ein Ergebnis man aus dem Clipboard erhält, wenn man etwas aus Excel in die Zwischenablage kopiert und das in einer Anwendung testet.

Auf diese Weise kann man auch auf XML-Basis eine ExcelTabelle auslesen.


class Program
{
     [STAThread()]
     static void Main()
     {
          System.Windows.Forms.IDataObject obj = System.Windows.Forms.Clipboard.GetDataObjekt;
          string excelSpreadsheetXML;
          try
          {
               System.IO.Stream memoryStream = (System.IO.Stream)obj.GetData("XML Spreadsheet");
               System.IO.StreamReader reader = new System.IO.StreamReader(memoryStream);
               excelSpreadsheetXML = reader.ReadToEnd();
          }
          catch{}

          if(!String.IsNullOrEmpty(excelSpreadsheetXML))
          {
               System.IO.File.WriteAllText(@"c:\excelClipboard.xml", excelSpreadsheetXML);
          }
     }

Leider lies sich aus unbekannten Gründen diese Xml nicht in System.Xml.LinQ.XDocument einlesen, aber das lässt sich sicher auch lösen.

Eine Zelle, die zwei Zellen verbindet sieht so aus:

<Cell ss:MergeAcross="1"><Data ss:Type="String">Doppelzelle</Data></Cell>

Das Attribut [ss:MergeAcross] ist also entscheidend. Einfach mal rumprobieren würde ich sagen. Ich kann ja schließlich nicht alles übernehmen ;)

Thema: Dokumentbezogene Anwendung - Excel 2003 - Bereitstellung für andere PCs
Am im Forum: Office-Technologien

(nächstes Bild)

Thema: Dokumentbezogene Anwendung - Excel 2003 - Bereitstellung für andere PCs
Am im Forum: Office-Technologien

Hallo zusammen,

derzeit versuche ich nur eines:
Eine dokumentbezogene Anwendung für Excel 2003 zu kompilieren und auszuführen,
welche lediglich eine MessageBox beim Start ausgibt. (testweise - denndas würde mir schon reichen)

Auf meinem Entwicklungsrechner geht das ohne Probleme - auch die CasPol-Registrierung führe ich für die Assembly durch.

Hier eine gegenüberstellung von Entwicklungsrechner und Zielrechner:
Entwicklungs-PC
- Windows XP SP 2
- Visual Studio 2008 Team System
- VSTO
- Office 2003 (Word, Excel, Power Point, ...)
- .Net 3.5
- Administrator-Rechte

Ziel-PC
- Windows XP SP 2
- Office 2003
- .Net 3.5
- eingeschränkte Benutzerrechte

Folgenden Fehler erhalte ich auf meinen Entwicklungsrechner, wenn ich nicht die CasPol-Registrierung durchgeführt habe:
(Fehlermeldung als Screenshoot im Anhang)

[B]Die Office-Dokumentanpassung ist nicht verfügbar.[/B]

Anpassungsassembly wurde nicht gefunden oder konnte nicht geladen werden.
Sie können das Dokument aber weiter bearbeiten und speichern.
Wenden Sie sich für weitere Informationen an den Administrator oder den Autor dieses Dokuments.

"Details" ----  "OK"
Nach der Caspol-Registrierung funktioniert alles so wie es soll.

Auf dem Ziel-PC hingegen sieht es völlig anders aus.
Egal ob mit oder ohne Caspol-Registrierung - immer kommt dieselbe Fehlermeldung:
(Fehlermeldung als Screenshoot im Anhang des nächsten Beitrags)
[B]Microsoft Office[/B]

Die Assembly * konnte in  nicht gefunden, oder konnte nicht geladen werden.

Sie können das Dokument jedoch weiter bearbeiten und speichern.
Kontaktieren Sie Ihren Administrator oder den Autor dieses Dokuments, um weitere Unterstützung zu erhalten.

"OK"

Leider bin ich mir nicht im klaren was zu tun ist.
Muss etwa Visual Studio und VSTO installiert werden?
Nach Rainbird ist das VSTO vorwiegend bei Add-Ins notwendig und ggf. sogar kostenpflichtig.

Ich habe auch ausprobiert, ob ich in Visual Studio (auf dem Entwicklungsrechner) beim Erstellen sage, dass die Assemblies, welche zum VSTO gehören, mitgegeben werden sollen (Lokale Kopie = TRUE), aber auch dann kam dieselbe Fehlermeldung beim Öffnen der .xls-Datei. Wobei dieser Trick z.B. auf einem Rechner mit .Net 2.0 funktioniert habt, bei dem die Anwendung die notwendigen .Net 3.5 Assemblies mitbekommen hat.

Gibt es eine Möglichkeit wie ich kurz und schlank meine Lösung auf verschiedenen Rechnern zum Einsatz bringen kann ohne das überall Software installiert werden muss?
Schließlich geht es nur um eine Vereinfachung einer Excel-Datei, welche am Ende verschiedene Erlöse und Kosten berechnen soll. Eine Sache die theoretisch auch unter VBA umsetzbar sein sollte. Aber ich bin ein C#-Programmierer und VBA scheint nichtmal .Net fähig zu sein.

Thema: xls Datei verändern: nur Werte ändern, Layout beibehalten
Am im Forum: Office-Technologien

Hallo chip777,

leider hast du nicht geschildert wie du die Datei einliest: binär, über OLE oder PIA.
Der Tipp von Verena bezieht sich auf die PIA (Primary Interop Assembly).

Zur Feststellung: Meinst du, dass die Datei, wenn sie gespeichert werden soll, nur die Änderung übernimmt, die du auch gemacht hast, anstatt die komplette Datei einmal neu zu schreiben?

Leider kann ich dazu nicht viel sagen, dann müsste ich schon wissen wie du die Datei einliest. Wahrscheinlich gibt es da einen Trick.

Thema: Primary Interop Assemblies OHNE Installation ??
Am im Forum: Office-Technologien

Funktioniert die Excel 2000 Variante, würde mich sehr interessieren.

Die COM-Interop-Schnittstelle ist ja lediglich nur eine Remotesteuerung und es kann ja nur gesteuert werden was da ist. Demnach ist der Link von dir zur MSDN ein Mittel der Steuerung zu sagen, was sie steuern soll.

Aber alternativ könnte es auch über OLE gehen. Bei Excel 2003 Dateien würde das so aussehen:

Zitat von dN!3L
Hallo w1z4rd2003,

hast du mal den Zugriff über OleDb ausprobiert?
Hier mal ein Snippet:


string fileName = "Mappe1.xls";
string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="""+fileName+@""";Extended Properties=""Excel 8.0;HDR=Yes""";

using (OleDbConnection oleDbConnection = new OleDbConnection(connectionString))
using (OleDbCommand oleDbCommand = oleDbConnection.CreateCommand())
{
	oleDbConnection.Open();

	oleDbCommand.CommandText = "CREATE TABLE [Tabelle6]([Text] Char,[Zahl] Integer,[Datum] Date)";
	oleDbCommand.ExecuteNonQuery();
	
	oleDbCommand.CommandText = "UPDATE [Tabelle6$] SET [Text]='Hallo'";
	oleDbCommand.ExecuteNonQuery();
}

Dieses Zitat ist etwas überarbeitet von mir und stammt ursprünglich von dN!3L.
Der Beitrag dazu ist hier.

Man müsste jetzt nur herausfinden, ob es auch bei Excel 2000 Dateien geht. Wobei es möglicherweise im Dateiformat nicht so große Unterschiede geben mag.