SaveDialog? wie funkt. speichern im C++Builder?

Ich habe eine ListBox, in der ich verschiedene Dateien markiert habe.
Diese möchte ich anhand eines Buttons speichern!!!

Ich habe also ein DialogSave gesetzt (wohin genau? ist das relevant?) und einen Button erstellt…welchen Code muss ich jetzt beim Button eingeben, sodass ich die markierten Felder speichern kann? (die markierten Dateien sind von einem FTP runtergeholt…)

könnte mir BITTE jemand ausführlich weiterhelfen?
THX!
Roman

falscher Dampfer
Hi Roman,

der SaveDialog dient der Auswahl einer Datei, die Du speichern willst. Wenn Du bereits Deine Dateien in einer Listbox vorliegen hast, in der Du einzelne Files markieren kannst, ist der SaveDialog überflüssig.

Was willst denn speichern ? Dateien vom FTP markieren, und dann bearbeiten, heisst im jargon eher ‚Öffnen‘. Wo sollen die Dateien hin, willste deren Inhalt bearbeiten, dann käme es auf die Dateitypen an. Oder die Dateien ins lokale Drive kopieren ? Bitte mehr Info.

Der SaveDialog kann an beliebiger Stelle in das Formualr gesetzt werden, da es eine unsichtbare Komponente ist, und erst während Laufzeit mit der Methode SaveDialog1->Execute zu einem sichtbaren Dialog wird. Willst Du mehrere Dateien gleichzeitig markieren, gib acht, dass in den Options der merker AllowMulitSelect gesetzt ist. Dann steht nach Schliessen des Dialoges die Dateinamen in dem Feld SaveDialog1->Files->Strings[].
Ob es Sinn macht,im Save mehrere Dateien anzugeben, sei dahingestellt.
For more details:RTFM

Ich habe eine ListBox, in der ich verschiedene Dateien
markiert habe.
Diese möchte ich anhand eines Buttons speichern!!!

Ich habe also ein DialogSave gesetzt (wohin genau? ist das
relevant?) und einen Button erstellt…welchen Code muss ich
jetzt beim Button eingeben, sodass ich die markierten Felder
speichern kann? (die markierten Dateien sind von einem FTP
runtergeholt…)

könnte mir BITTE jemand ausführlich weiterhelfen?

Bitte nicht so schreien, meine Ohren…

THX!
Roman

NEUE INFOS
Erstmal vielen vielen Dank für die Mühe die du dir machst!
ich habe so gebrüllt, da mir das unheimlich wichtig ist :smile:

also, in den Options habe ich nicht MultiSelect eingestellt, habe es mit der Codezeile:
lstArchives->MultiSelect=true;

(IstArchive ist in dem Fall die ListBox)
In dieser ListBox sind also Dateien, also die Namen der Dateien angegeben, die ich per FTP geholt habe.
Diese Dateien kann ich, wenn ich die doppelklicke, links anzeigen lassen… so ne art textdateien…
aber das was ich machen soll ist, das man mehrere Dateien auswählen kann (das war ja nicht das Problem) und diese dann abspeichern kann!

Das Problem ist, ich programmiere zwar schon eine ganze weile, aber nicht mit dem Builder!
und das Programm ist von jemand anderes geschrieben!
also ist der durchblick…im moment gleich 0!

ich denke du müßtest die ganzen ftp daten haben, die in dem programm integriert sind oder?
aber ich hoffe immernoch das man durch die listbox die dateien abspeichern kann.
natürlich auf der festplatte abspeichern.

würde mich freuen wenn du mir das genauer erklären könnenst…
nicht „allzu“ fachsimplisch… :wink:
vielleicht unter anderem den code, dass ich durch einen button die markierten (oder DIE MARKIERTE, anderes gehts ja nicht) datei abspeichern kann auf der platte an einem beliebigen platz, den ich dann bei „speichern unter“ wählen kann!

das wäre perfekt, denn ich kann das leider nicht!
zum schluss noch eine für dich wahrscheinlich dumme frae:
was meinst du damit? For more details:RTFM

und, vielleicht auch noch diese frage:
(denke aber mal das das für nicht nicht so schwer sein wird… :smile: :

Ich soll diese ListBox Dateien, (wieder Bjeweils Button dazu einbauen),also die Namen die in der ListBox angezeigt werden, jetzt nach Datum, Händlernummer usw sortieren lassen.
wie greift man darauf zu?

Ich habe auch schon wirklich stundenlang im netz gesucht, aber da finde ich weiß gott keine antwort darauf :smile:

vielen dank
roman

zaghafter Versuch
Roman,

lass mich zusammenfassen: Du hast ein bestehendes Programm, dass Dateinamen in einer Listbox anzeigt. Durch Selektieren eines Dateinamens und anschliessendem Click auf einen Button soll ein Dialog öffnen, in der ein Laufwrek, ein Verzeichnis und ein Dateiname eingegeben oder ausgewählt werden kann. Durch Schliessen des Dialogs mittels OK Button wird die Datei der Listbox in die eingegebene Datei kopiert (die vorzugsweise auf einem lokalen Laufwerk liegt).
Soweit richtig ?

Also:
Auf dem Formular zusätzlich einen SaveDialog und einen Button plazieren.
Dem SaveDialog evt. ein Startverzeichnis und ein Filter angeben.
Im OnClick Ereignis des Buttons steht:

if (lstArchives-\>Selected[lstArchives-\>ItemIndex])//die Datei ist selektiert
{
 if(SaveDialog1-\>Execute())
 {
 ExtFileCopy(lstArchives-\>Items-\>Strings[lstArchives-\>ItemIndex], SaveDialog1-\>FileName);
 } 
 }
}

Dazu die Funktion (kopiert und modifiziert aus :
http://bytesandmore.de/rad/cpp/snipp/sc01010.php

int TForm1::ExtFileCopy(AnsiString slSourceFile, AnsiString slDestFile)
{
 int ilBufSize = 8192; // Puffer-Grösse
 bool blRetVal = false; // Rückgabewert
 int ilSourceHandle, ilDestHandle; // Dateien-Handles
 DWORD ilFileSize = 0; // Dateigrösse
 DWORD ilBytesTotal = 0; // Anz. der bereits kopierten Bytes
 int ilBytesLastWrite = 0; // Anz. der im aktuellen
 // Schleifendurchlauf kopierten Bytes
 double dlLastValue = 0; // zuletzt ausgegebener Fortschrittswert
 int ilBytes = 0; // Anz. der in Lesepuffer eingelesenen
 // Bytes
 // Falls ein Verzeichnis als Name der Zieldatei übergeben, Namen der
 // Quelldatei an den Verzeichnisnamen anhängen:
 int ilAttr = FileGetAttr(slDestFile);
 if (ilAttr != -1 && ilAttr & faDirectory)
 slDestFile = IncludeTrailingBackslash(slDestFile) +
 ExtractFileName(slSourceFile);
 // Falls Namen der Ziel- und Quelldatei identisch, abbrechen:
 if(!slDestFile.AnsiCompareIC(slSourceFile)) return false;
 // Quelldatei öffnen:
 ilSourceHandle = FileOpen(slSourceFile.c\_str(),fmOpenRead);
 if(ilSourceHandle \>= 0)
 {
 // Die Dateigrösse ermitteln:
 ilFileSize = GetFileSize((HANDLE)ilSourceHandle, NULL);
 if(ilFileSize != 0xFFFFFFFF)
 {
 // Zieldatei öffnen:
 ilDestHandle = FileCreate(slDestFile.c\_str());
 if(ilDestHandle \>= 0)
 {
 // Schreib- / Lesepuffer erzeugen:
 char \*cpBuffer = new char[ilBufSize];
 if(cpBuffer)
 {
 blRetVal = true;
 while(ilBytesTotal 

BTW:RTFM 

By the way: read the fine manual

wobei es in der Interpretation des 'F's Varianten gibt, geläufig ist eher das f\*cking....


Sortieren:
Dazu muss die Eigenschaft Sorteed auf false stehen, denn Du willst (musst) es ja selbst sortieren.
Nach Namen sortieren:
einfach Sorted auf true

Nach Datum, Autor, oder so:
Aus jedem File Datum,Autor, ... auslesen, dann die Liste neu aufbauen nach dem jeweilgien Sortierkriterium. Ein ähnliches Beispiel fidnest Du hier:
http://bytesandmore.de/rad/cpp/snipp/sc05002.php
Dabei ist der Eingabeparamtere dieser Fkt die Items Liste Deiner Listbox, also:
NumStringSort(lstArchives-\>Items);

anstatt nach Nummern zu sortieren , sollte die Funktion umgeschrieben werden, sodass nach Dienen eigenen Sortierkriterien sortiert wird. Oje, das könnte etwas Arbeit machen.

Meine Heransgehensweise wäre eher, beim Erstellen der ListBox Liste aus den Dateien gleich Datum, Autor u.ä. rauszuholen und temporär in eine TList zu speichern, um so bei der gewünshcten Sortierung darauf zurückzugreifen, ohne die Datei neu öffnen zu müssen. TList bringt auch gelich eine Methode Sort() mit, bei der die vergleichsfunktion augetauscht werden dann.

Übrigens: Wer hat Dir eigentlich dieses Ei ins Nest gelegt, mit dem Builder gleich so ins Eingemachte zu gehen, wenn Du noch keinen Dunst vom BCB hast ?

Gruss
Hans
P.S. Bin gleich weg, tausche Büro gegen Bodensee, meine Abschalttemperatur ist überschritten, bin morgen wieder erreichbar, hier im forum oder per email.


> <small>[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]</small>

… schock …
Hehe, also dieses Ei habe ich mir selber ins Nest gelegt!
Sozusagen.
Denn ich mache hier ein Praktikum bei Toyota, und was sollen die mir anderes für eine Aufgabe gebe?

Ich habe gerade nur an deiner Mühe erkannt, dass es für mich UNMÖGLICH wäre, diesen Code selber zu schreiben, und ich denke ich schaffe das auch nicht.

Morgen werde ich deinen Quelltext mal eingeben und versuchen, daran herum zubasteln…
…vielleicht ist er ja so flexibel, das er gerade bei mir fast genau passt :smile:

werde dann morgen denke ich mal auf dich zurück kommen…

vielen dank nochmal!
bis dann wahrscheinlich morgen,
roman

ALSO, auf ein Neues…
morgen hans

also, ich habe übrigens 2 monate zeit für diese aufgabe/n.
es wäre aber supergeil, wenn ich nach diesen 2 monaten die aufgabe mit dem speichern schaffen würde, dann wäre das praktikum wirklich perfekt!
ich habe es dann zwar nicht selber geschafft, aber egal.
ich mache nebenbei, wenn ich auf deine antwort warte, einen grundkurs in CBulder…wenn ich dann aus dem praktikum komme, kann ich es ja einigermaßen, zumindest die strukturen verstehen!

erstmal zu deinen ersten code:

if (lstArchives->Selected[lstArchives->ItemIndex]) //die Datei ist selektiert
{ if(SaveDialog1->Execute())
{ ExtFileCopy(lstArchives->Items->Strings[lstArchives->ItemIndex],
SaveDialog1->FileName); } }

–>> ExtFileCopy erkennt er nicht an!
–>> call to undefined function (ExtFileCopy) …
ist so wiso mein fehler, das es nicht geht, aber… :smile:

hier ist jetzt mal ein code aus dem vorhandenen quelltext:

if(lstArchives->ItemIndex>=0)
{
// Hier unterscheiden zwischen FTP oder Copy
memoStatus->Lines->Add(„Datei wird übertragen“); // ist nur ein fenster indem was angezeigt wird…

// dbl->FTPRemoteFile = lstArchives->Items->Strings
[lstArchives->ItemIndex];
dbl->FTPRemoteFile = ItemList->Strings[lstArchives->ItemIndex];
dbl->GetData();
// Übertragene Datei öffnen
ReadFile(dbl->FTPLocalPath + dbl->FTPRemoteFile);
PrintKontrollbogen();
}
–>> ich habe nur das der erklärung zu „memoStatus“ geschrieben.
–>> oben hat jemand dazu geschrieben "hier unterscheiden zwischen FTP
oder Copy…was soll das?
–>> kann ich mit diesem teil des quelltextes arbeiten?
–>> die IP des FTP wird über die .INI Datei geholt…

in dem programm ist ja schon eingebaut, dass wenn man auf einedatei klickt, diese dann in einem memo fenster daneben angezeigt, also eigentlich ja schon geholt wird!
kann ich darauf nicht zurück greifen?
wenn der quelltext ausschnitt oben überhaupt nix nützt, dann müsste aber doch irgendwo anders schon so etwas ähnliches vorhanden sein…damit ich die datei speichern kann, oder nicht?

thx
verzweifelnder roman

da bin ich wieder !
Hallo Roman,

nicht verzweifeln:

  1. Zwei Monate Zeit sind ja mehr als üppig für diese Aufgabe
  2. Die erste Regel der Programmierer ist: Wenn 90% der Projektzeit verstrichen sind, sind noch 90% der Aufgabe zu erledigen. Also wirds im Oktober erst richtig hektisch.

Zu Deinen Fragen:
Der Compiler meckert, weil er nicht weiss, wo die Funktion ExtFileCopy zu finden ist.
Daher musst Du im Header File (*.h) die Funktion bekannt machen, bevorzugt als Teil der Formularklasse. Dazu:
Zu deinem Formular das zugehörige header File suchen, dort steht irgendwo die

class Formx:stuck\_out\_tongue:ublic TForm {...

und darin ein Abschnitt

private:

. Füge dort eine Zeile

ExtFileCopy(AnsiStrin,AnsiString);

ein. Jetzt ist die Funktion als Teil der Klasse bekannt. Achte im CPP File darauf, dass die Funktion ExtFileCopy wirklich Teil der Klasse ist, indem der richtige Klassenbezichner bei der funktion steht, also:

TFormx::ExtFileCopy(...

wobei Du natuerlich den namen Deiner Formularklasse benutzen musst.

Dein zusätzlicher Code zeigt, dass eine Funktion ReadFile exisitiert, die (anscheinend) den Inhalt der ausgewählten Datei lesen kann. Diese wird mit PrintKontrollBogen (anscheinend) angezeigt. Schau in ReadFile nach, wie und wo die gelesenen Daten abgelegt werden, und setzte dort an, diese Daten dann in ein lokales File zu schrieben.
Das Objekt dbl scheint für das Dateihandling der FTP Daten zuständig zu sein, man weist einen Namen zu (FTPRemoteFile) und kann dann GetData aufrufen. Was macht getData ?

Wie gesagt, die Hälfte der Lösung hast Du schon, die Daten liegen irgendwo im Speicher und müssen nur noch in passender Form auf die Platte gebrezelt werden. Nur Mut, Roman, das schaffst Du.

Wer hat eigentlich den Originalcode geschrieben ? Auffalend ist die ausufernde Benutzung von Kommentaren und die Verwendung von aussagefähigen Variablen- und Funktionsnamen, in diese Branche eher unüblich. Mein Lieblingskommentar ist übrigens :

//not the final solution

Wer das liest erkennt, dass ich mir ehrlich Gedanken zu dem Problem gemacht habe, aber in der Eile nur eine Schnelllösung hingezaubert bekommen hab, die jederzeit verbessert werden könnte…

Gruss
Hans

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

neue fehler, neue fragen…
Hi Hans.

Schön das du mir mut machst!
Das hat etwas genützt! :smile:

also den orginalcode hat hier jemand bei toyota geschrieben…
…denke mal, dass er wenig zeit hatte, und deshalb //not the final version
hingeschrieben hat! …

… das mit der Funkton bekannt machen hat eigentlich gut geklappt,bis auf neue fehlermeldungen…
und das wären folgende:

" Cannot convert ‚System::AnsiString‘ to ‚int‘ "
" Type mismatch in parameter 'AnsiStrin’in call to
‚TFormKontrollbogen::ExtFileCopy(int,System::AnsiString‘) "

du kannst dir sicher vorstellen, dass ich damit eher wenig anfangen kann :wink:

der code sieht bei mir folgendermaßen aus… dein code eben nur übernommen:

if (lstArchives->Selected[lstArchives->ItemIndex]) //die Datei ist selektiert{
{
if(SaveDialog1->Execute())

{ TFormKontrollbogen::ExtFileCopy(lstArchives->Items->Strings
[lstArchives->ItemIndex], SaveDialog1->FileName);
}
}
}

du sagst so leicht „in der ReadFile“ nachschauen, und ich soll schauen, wo die gelesene datei abgelegt wird usw…
aber naja, :smile:
ich kopiere dir nochmal einen auschnit aus der ReadFile Fkt.:


void __fastcall TFormKontrollbogen::ReadFile(AnsiString Filename)
{
bool flNetto;
Position = 1;
char buffer[19000];

sb-&gt:stuck_out_tongue_winking_eye:anels->Items[0]->Text = "Datei: " + ExtractFileName(Filename);

FILE *fp = fopen(Filename.c_str(),„rt“);

if(!fp)
{
Application->MessageBox(„Datei konnte nicht geöffnet werden“,„Fehler“,mbOK);
return;
}

SendMessage(memoDatei->Handle, WM_SETREDRAW, 0, 0);
fgets(buffer, 19000, fp);
AnsiString str = buffer;
memoDatei->Lines->Clear();
memoDatei->Lines->Add("");
… usw


erkennst du hier wo die datei gespeichert wird?

die aussagefähigen varibalen und die daokumentation ist so auffalend reichhaltig, weil dieser programmierer sagte, dass er das mache, um sich nachher bestmöglich zurecht zu finden…

meinst du, du kannst mir irgendwann den code schreiben, für GetData?
sag mir einfach, was du von dem quelltext noch sehen mußt, um mir zu der lösung zu helfen! :smile:

es gibt da noch diese funktionen:
readinifile()
SearchArchives()
MLog(int status,AnsiString msg)
FindeFTPArchiv()
DoLogin()
ReadFile(AnsiString Filename)
SplitAndOut(AnsiString &str,int length,int show)
Getdbl(AnsiString str,bool flNetto)
GetDate(AnsiString str)

die hören sich ja alles irgendwie wichtig an, und sind denk ich male vom name her schon aussagekräftig genug…

diese codezeilen sind vielleicht auch noch wichtig:
aus ReafIniFile():


FTP.LocalPath = ExtractFilePath(Application->ExeName) +
ini -> ReadString(„FTPINFO“,„LOCALPATH“,"");

mkdir(FTP.LocalPath.c_str());


vielen vielen dank für deine mühe.
du erklärst das echt gut. :smile:
wie lange programmierst du schon?

thx
roman

still not the final solution

Hi Hans.

Schön das du mir mut machst!
Das hat etwas genützt! :smile:

Das war mein Ansinnen !

also den orginalcode hat hier jemand bei toyota geschrieben…

aah, die beiden Affen aus der Werbung ?

" Cannot convert ‚System::AnsiString‘ to ‚int‘ "
" Type mismatch in parameter 'AnsiStrin’in call to
‚TFormKontrollbogen::ExtFileCopy(int,System::AnsiString‘) "

jau, Du hast meinen Fehler abgetippt, im header File fehlt ein g :

(AnsiString,AnsiString)

die aussagefähigen varibalen und die daokumentation ist so
auffalend reichhaltig, weil dieser programmierer sagte, dass
er das mache, um sich nachher bestmöglich zurecht zu finden…

…sprachs und machte sich aus dem Staub…

vielen vielen dank für deine mühe.

…jau, ich such etwas Ablenkung…

du erklärst das echt gut. :smile:

…Danke für die Blümchen…

wie lange programmierst du schon?

…so 25 Jahre, aber C++Builder erst 6 Jahre…

thx
roman

Ein email ist unterwegs an Dich.
bye, Hans