C# i MS Word

0

Witam wszystkich,
Mam taki problem i chciałbym prosić o pomoc. Mam aplikacje desktopową napisaną w języku c# i chciałbym by program wpisał w odpowiednie miejsca zmienne w wordzie lub wygenerowal cały dokument MS word. Nizej zamieszczam przykład jak miałoby to wyglądać:

      Oświadczenie                        data: "textbox1"

Ja "textbox2" "textbox3" oświadczam, że użytkownik "textbox4" ukończył dzisiejsze zawody na miejscu "zmienna".

Chciałbym aby ktoś napisał mi czy jest jakaś specjalna funkcja do generowania takiego pliku i czy ktoś zamieścił jakiś przykład i wytłumaczył go bo nie wiem jak się do tego zabrać.
Dziękuję za pomoc i pozdrawiam

0

Poszukaj informacji o Microsoft.Office.Interop.Word.

0

Dziękuję za zainteresowanie tematem. Przed założeniem tematu przeczytałem troche o tej bibliotece natomiast wygląda mi ona dosyć skomplikowanie jeśli chodzi o MS Word i nie wiem zbytnio jak mógłbym za pomocą tej biblioteki stworzyć taki szablon i wypełnić go zmiennymi w danym miejscu w dokumencie.

0

http://maciej-progtech.blogspot.com/2009/08/open-xml-tworzymy-dokument-word-docx.html Z użyciem tego generuje złożone zamówienia z tabelkami etc.

0

Witam ponownie,
Zastanawiam się czy jest taka możliwość, aby mój plik Word zrobić jako wzorzec i nie generować go z poziomu C# tylko pobierać przeszukać i podmienić określone wyrazy tymi które znajdują się w textboxie u mnie? Jak najprościej takie coś zrobić?

2

Zastanawiam się czy jest taka możliwość, aby mój plik Word zrobić jako wzorzec i nie generować go z poziomu C# tylko pobierać przeszukać i podmienić określone wyrazy tymi które znajdują się w textboxie u mnie?

To będzie najprościej zrobić całkowicie w Wordzie z wykorzystaniem skryptów VBA. Naciśnij sobie w Wordzie alt + F11, ukaże ci się edytor skryptów. Możesz tu dodawać formatki, które potem możesz przypisać do przycisku na pasku narzędzi / wstążce. Na formatce możesz umieścić textboxa, a tymczasem w normalnym edytorze przygotować szablon (zapisać jako dot/dotm). Kluczowe będzie tak naprawdę oznaczenie w dokumencie miejsc, które chcesz wypełniać na podstawie textboxa - ja bym do tego wykorzystała style.

Inna sprawa, że cały dokument możesz przygotować po stronie C#, wtedy po stronie C# będziesz miał kompletną kontrolę nad tym co się dzieje.

0

na razie udało mi się pobrać wzorzec który zrobiłem wcześniej i na podstawie porównań podmienić określony wyraz moim wyrazem w aplikacji.
Do porównania użyłem kodu:

foreach (Word.Range tmpRange1 in docnew.StoryRanges)
{

                tmpRange1.Find.Text = "txtbox2";
                tmpRange1.Find.Replacement.Text = textBox2.Text;


                tmpRange1.Find.Wrap = Word.WdFindWrap.wdFindContinue;


                object replaceAll = Word.WdReplace.wdReplaceAll;


                tmpRange1.Find.Execute(ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref replaceAll,
                    ref missing, ref missing, ref missing, ref missing);
            }

Jednak we wzorcu zawarłem tylko nagłówek całej strony a reszta chciałbym żeby się generowała w zależności od kliknięcia przycisku w aplikacji.
Mój problem polega na tym obecnie że nie wiem jakiej funkcji użyć żeby dopisać coś na końcu mojego tekstu (bez nadpisywania) oraz jak zrobić przejście do nowej linii (odpowiednik endera w wordzie)?

1
Dim s as String

s = tmpRange1.Text
s = s + "nowy tekst na końcu" + vbCrLf + "tekst w nowej linii"
tmpRange1.Text = s
0

Dziękuję bardzo za podpowiedź. A czy można z poziomu c# ustawiać wielkość czy rodzaj czcionki jaka będzie użyta w wordzie?
Jeśli tak to jakie polecenie w c# odpowiada za to?
Ogólnie poszukuje jakiegoś sensownego artykułu opisującego całą komunikację worda z c# ale cieżko coś takiego znaleźć.

0

Mam kolejne pytanie z tych magicznych dla mnie :-)
Chodzi o formatowanie tekstu z poziomu c#. Konkretnie chodzi o pogrubienie tekstu. Robię to w następujący sposób:

Word._Document wordDocument = word.Documents.Add(
   ref missing, ref missing, ref missing, ref missing);

        Word.Range rng = wordDocument.Range(); ;

        rng.Font.Size = 10;
        rng.Font.Name = "arial";
        rng.Font.Bold = 1;
        word.Selection.TypeText("text");
        rng.Font.Bold = 0;
        word.Selection.TypeText("text2, "+dt+ Environment.NewLine);

Problem polega na tym, że chcę aby pierwszy tekst był pogrubiony a ten drugi już normalny a z boldem jako "true" pogrubia całość a na "false" jest normalny cały dokument. Nie wiem gdzie robie błąd :-/ Mam jeszcze pytanie czy wie ktoś jak w C# ustawić interlinie na 1,0 oraz wyśrodkowanie tekstu?
Z góry dziękuję za pomoc

0

Range to jest taki typ danych w Wordzie określający pewien fragment tekstu. Ty w swoim przykładzie operujesz na range'u CAŁEGO dokumentu, stąd zmiany dotyczą całego dokumentu.
Zamiast tego, utwórz np. 2 akapity (paragraph), ustaw oddzielny range na pierwszy i oddzielny na drugi. Poczytaj ogólnie o modyfikacji Range, bo możesz go ustawić nawet na konkretną literę w tekście.

0

Dziękuję za pomoc:-) Chciałbym jeszcze prosić o jedną pomoc. chciałbym, żeby po kliknięciu buttona1 program otworzył worda i skopiował do niego tekst. Później chciałbym aby po kliknięciu button2 do tego dokumentu pod spodem inny tekst. Próbowałem to zrobić w najprostszy sposób jaki mi przyszedł do głowy a mianowicie utworzenie obiektu o takiej samej nazwie i próba doklejenia tekstu lecz w rezultacie otrzymałem dwa dokumenty o różnych treściach. Oto fragment kodu:

object missing = Type.Missing;
Word._Application word = new Word.Application();

Word._Document wordDocument = word.Documents.Add(
ref missing, ref missing, ref missing, ref missing);

            Word.Range rng = wordDocument.Range(); ;

            rng.Font.Size = 10;
            rng.Font.Name = "arial";

            string dt = DateTime.Now.ToShortDateString();
             word.Selection.TypeText("Tekst1");

W jaki sposób utworzyć obiekt żeby po kliknięci buttona dopisał do już otwartego dokumentu inny tekst?

0

Próbowałem to zrobić w najprostszy sposób jaki mi przyszedł do głowy a mianowicie utworzenie obiektu o takiej samej nazwie

O nie nie nie. Nie ma sensu tworzenie obiektu o takiej samej nazwie! Należy skorzystać z tego samego obiektu.

public class Form1 : Form
{
private Word._Application word;
Word._Document wordDocument;

public Form1()
{
InitializeComponents();
word = new Word.Application();
wordDocument = word.Documents.Add(
ref missing, ref missing, ref missing, ref missing);
}
private void button1_Click(object sender, EventArgs e)
{
//tu dodaj sobie jeden tekst do obiektu word
}
private void button1_Click(object sender, EventArgs e)
{
//a tu dodaj sobie drugi tekst do obiektu word
}

0

Dziękuję ci bardzo za pomoc i zainteresowanie aurel:-) Kierując się twoimi wskazówkami kompilator wszystko pięknie przyjął natomiast problem pojawia się podczas dodania tekstu. Program się wysypuje zgłaszając wyjątek: "NullReferenceException nie został odsłużony, odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu". Orientuje się ktoś czego dotyczy się ten wyjątek i jak go obsłużyć?
Dodam że wyjątek wyskakuje przy poleceniu "Word.selection.."

0

Wyjątek dotyczy tego, że próbujesz wywołać metodę obiektu, który nie istnieje. Najpierw utwórz obiekt, a potem na nim operuj.

0

Tylko problem w tym, że obiekt mam utworzony tylko nie w obsłudze danego buttona tylko globalnie. jeśli utworzę ten obiekt w obsłudze buttona to wszystko działa poprawnie. Oto kawałek kodu odpowiadający za to:

public partial class Form1 : Form
{
private Word.Application word;
Word.Document wordDocument;
public Form1()
{
InitializeComponent();
object missing = Type.Missing;
Word.Application word = new Word.Application();

         wordDocument = word.Documents.Add(
   ref missing, ref missing, ref missing, ref missing);

      
        
    }

private void button4_Click(object sender, EventArgs e)
{

        word.Selection.Font.Bold = 1;
        word.Selection.TypeText("tekst1);
   }

private void button1_Click(object sender, EventArgs e)
{
word.Selection.Font.Bold = 1;
word.Selection.TypeText("tekst2");
}

0

A który obiekt jest null?

0

A w jakim celu miałby być null? Tworzę obiekt typu Word.Aplication oraz Word.document jako globalne, czyli dokument jest otwarty i oczekuje na dopisywanie, a że jest widoczny dla całej aplikacji powinien zadziałać bez problemu ale chyba gdzieś jest błąd w moim rozumowaniu.

0
private Word.Application word; //co prawda tutaj deklarujesz sobie word Word.Document wordDocument; public Form1() { InitializeComponent(); object missing = Type.Missing; Word.Application word = new Word.Application(); //ale tu inicjujesz zupełnie inny word....
         wordDocument = word.Documents.Add(
   ref missing, ref missing, ref missing, ref missing);            
    }
...a potem korzystasz z word tego globalnego, nie zainicjowanego.

Powinno być:
<code class="c#">
        private Word.Application word;    //co prawda tutaj deklarujesz sobie word
        Word.Document wordDocument;     
        public Form1()
        {
            InitializeComponent();
            object missing = Type.Missing;
            word = new Word.Application();     //ale tu inicjujesz zupełnie inny word....

             wordDocument = word.Documents.Add(
       ref missing, ref missing, ref missing, ref missing);            
        }
0
Cristiano1989 napisał(a):

A w jakim celu miałby być null?

Skoro w Twoim kodzie rzucany jest NullReferenceException, to znaczy, że masz tam null, a nie powinieneś go mieć. Zatem sam sobie odpowiedz na pytanie, po co Ci ten null.

0

ehhhhh, coś czuję, że temat jeszcze będzie się ciągnął, ale do rzeczy, wg. mnie @Cristiano1989 rzuciłeś się na wysoką wodę, jeśli tylko operujesz podstawami programowania w C#, dla pocieszenia: jeśli będziesz coś jeszcze robił w C#, powiązane z MS Office (Word, Excel, Access), no to to niestety będzie pracochłonne i męczące, sam się o tym przekonałem, dosyć niedawno, nawet :P

ps. nie mam twojego, całego projektu przed oczami, ale ja bym się zorientował na twoim miejscu jaki jest ten 'obiekt' null i bym go wywalił na zbity próg ;)

0

Problem rozwiązany dzięki pomocy @aurel za co bardzo dziękuję. :-) Co do wypowiedzi @Docent to przecież od tego są takie fora, żeby ludzie którzy już to umieją przekazywali tym co się uczą. Tak się składa, że od roku pracuje zawodowo jako programista C#, lecz to nie przeszkadza w fakcie, że chcę się nauczyć czegoś nowego a w tym przypadku jest to biblioteka Office. Za niedługo przyjdzie czas na Excella i jak będę miał problemy to nie będę się wahał zapytać na forum o pomoc.

Co do programu to chciałem zapytać o ostanią rzecz, a mianowicie czy można tak obsłużyć kursor, żeby ustawił się na początku kolejnej strony?

0

Co do programu to chciałem zapytać o ostanią rzecz, a mianowicie czy można tak obsłużyć kursor, żeby ustawił się na początku kolejnej strony?

Jeżeli pisząc kursor masz na myśli tą migającą kreskę w tekście, to tak - w tym celu musisz zmienić Selection. W VBA w tym celu wykorzystuję Selection.MoveEnd i Selection.MoveStart, w C# będzie pewnie coś podobnego. Ewentualnie możesz najpierw ustawić sobie Range w odpowiednim miejscu, a następnie na tym Range'u wywołać metodę Select.

Jeżeli natomiast chodzi ci o kursor myszki, to sobie tego nie wyobrażam :)
No dobra, wyobrażam sobie, ale jest to brzydkie i niesmaczne, więc nie będę się tymi fantazjami dzielić ;)

0

Dziękuję @aurel za pomoc :-) w C# jest dokładnie tak samo jak w VS Basicu i chodziło właśnie o ten mrugający kursor :-D Jeszcze raz bardzo dziękuję za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1