Ankieta w delphi.

0

Witam i pozdrawiam. Dawno mnie u Was nie było widzę wiele zmian na lepsze. Potrzebuję pomocy w budowie małego programu byłby to program ankieta tzn wyświetlałby pytania i odp z jakiegoś pliku ini czy bazy danych(ankieta wielokrotnego wyboru czyli komponenty checkbox by mnie interesowały) potem użytkownik ją wypełnia a wyniki są zapisywane do oddzielnego pliku który będzie zawierał już tylko pytanie i udzielone na nie odp. Mam nadzieję że bardzo nie namieszałem i zrozumiecie o co mi chodzi. Prosiłbym o konkrety bo dawno nie pisałem w Delphi mniej czasu praca i w ogóle... Z góry dzięki.

0

Tak jak wspomniałeś do przechowywania może być plik ini, ale lepiej będzie zastosowac ładowany z zasobów
plik typu xml. Polecam do tego darmowy parser z http://spook.freshsite.pl/files/download/spkxmlparser.zip
jeżeli używasz Delphi 7 Personal to się przyda, bo nie ma w wersjach Personal komponentów do xmla. Teraz
co do odpowiedzi to najprościej pakować taki plik zlibem - zawsze będzie nieco mniejszy i "zakodowany", no
a potem ja bym wysyłał go ftpem na jakieś tymczasowe konto założone na jakimś hostingu. Do tego celu - to
polecam komponenty Synapse. Przykłady użycia oby komponentów można znaleźć na googlach spokojnie, a o
ile znałbyś nieco php (w czym nie pomogę) możesz zrobić bardziej bezpieczną formę wysyłania pliku, który w
odpowiednim momencie zapisywał byś w katalogu tymczasowym na chwilę - ewentualnie pakował zlibem albo
jakimś innym modulem, ale ten jest wbudowany w Delphi począwszy na pewno od siódemki, więc łatwiej i na
jakimś serwerze miał umieszczoną stronę która pozwalała by przesłać na nią pliki tak jak serwisy hostingowe.
Link mógłby być zakodowany w programie. Do wysyłania również Synapse się nada. Tylko wtedy kwestia, co
ma być po stronie skryptu php, ale jak widzę na http://www.kess.snug.pl/?sid=10&pid=38 - to nie problem.

0

Chyba zatrzymam się na etapie ręcznej wysyłki/wydruku pliku, a co do xml jak i reszty tzn ładowanie z i do pliku prosiłbym o pomoc. Tak D7P.

0

No to co do XMLa, to zobacz sobie mój przykładowy program który kiedyś napisałem w chwili wolnego czasu
którego mam raczej sporo :) Tam będziesz widział jak zrobić odczyt. Oraz mój testowy projekt !SPK_XML,
w ktorym testowałem sobie zapis i odczyt do XMLa. Kod bałaganiarski nieco może, ale powinieneś raczej bez
trudu dzieki niemu pojąć podstawy zapisu oraz odczytu XMLa przy pomocy tego parsera. A oto dwa adresy:

http://www.speedyshare.com/files/21436715/translator.rar
http://www.speedyshare.com/files/21436727/_spk_xml.rar

Natomiast co do uploadu plików poprzez http://www.kess.snug.pl/?sid=10&pid=38y nam taki skrypt, który w
oryginale jest na wspomnianej stronie http://www.kess.snug.pl/?sid=10&pid=38 - ja zapisałem go na ftpie
konta www na serwerze cba.pl (do datmowych prostych rozwiązań powinien wystarczyć) jako plik a.php jest
to ważne bo w kodzie jak widzisz jest również a.php jeżeli chcesz zapisać go pod inną nazwą to w kodzie tu
poniżej zmieniasz a.php na nazwa_twojego_pliku.php - w kodzie jest również zawarta wartość która określa
ile bajtów może miec maksymalnie wysyłany plik. Ja ustawiłem ów wartość na 10000 bajtów. Dla plików xmla,
w miare prostych - dodatkowo spakowanych ZLibem - to powinno wystarczyć. Także poniżej kod pliku php:

<?php
echo '<?xml version="1.0" encoding="iso-8859-2"?>';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-
transitional.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-2" />
<title>Upload</title>
</head>
<body>

<div>
<form enctype="multipart/form-data" action="a.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="10000" />
<input name="plik" type="file" />
<input type="submit" value="Wylij plik" />
</form>
</div>

<?php
$plik_tmp = $_FILES['plik']['tmp_name'];
$plik_nazwa = $_FILES['plik']['name'];
$plik_rozmiar = $_FILES['plik']['size'];

if(is_uploaded_file($plik_tmp)) {
     move_uploaded_file($plik_tmp, "upload/$plik_nazwa");
    echo "Plik: <strong>$plik_nazwa</strong> o rozmiarze
    <strong>$plik_rozmiar bajtów</strong> został przesłany na serwer!";
}
?>
</body>
</html>

A to kod w Delphi ktory elegancko przy użyciu tego formularza nam wyśle rządany plik, a rezultat kodu html,
jaki zwróci strona pokaże w tekstcie Memo1, ale możesz również zwrócić rezultat do niewidocznej StringList
jeżeli nie chcesz go widzieć na ekranie, bo widoczność zwróconej strony posłuży raczej do testów. Oto kod:

const
  Base_Url = 'http://twoj-adres.net/a.php';
var
  SL : TStringList;
  MS : TMemoryStream;
begin
  SL := TStringList.Create;
  MS := TMemoryStream.Create;
  MS.LoadFromFile('D:\plik.cos');
  HttpPostFile(Base_Url, 'plik', 'nazwa_pliku_wynikowego.aaa', MS, SL);
  if Pos('został przesłany na serwer', SL.Text) > 0 then
  begin
    ShowMessage('Plik wysłany na serwer.');
  end
  else
  begin
    ShowMessage('Nie wysłano pliku!');
  end;
  SL.Free;
  MS.Free;
end;

Ten kod na ogół się powiedzie (z mojego testu wynika), że nawet mimo ograniczenia rozmiaru do 10000 B,
był w stanie odebrać większy plik. Wynika to ze sposobu wysyłania przez moduł httpsend i ów funkcję. Tak
więc lepiej zakoduj jakoś link do wysyłania, chociaż Wiresharkiem albo innym snifferem chętni i tak jak coś
będą chcieli wysłać to podejrzą co wysyła Twoja aplikacja, jak się przed tym ustrzec. Niebardzo wiem ;/ A i
co ważne dla skryptu a.php - katalog upload musi istnieć na serwerze i mieć ustawione prawa 777 - czyli są
to pełne prawa dla Ciebie, grupy oraz pozostałych. Bez problemów pliki wgrasz na serwer FTP oraz ustawisz
im te atrybuty pod TotalCommanderem. Co do Synapse jeszcze to po pobraniu do katalogu z projektem - o
ile chcesz działać z dodanym modułem httpsend do sekcji uses, potrzebujesz tylko takich plików - z tej listy:

blcksock.pas
httpsend.pas
sswin32.pas
synacode.pas
synafpc.pas
synaip.pas
synautil.pas
synsock.pas

Co do zapisania pliku XML do katalogu tymczasowego. To jak pobrać katalog tymczasowy masz w googlach.
Jak spakować ewentualnie modułem ZLib wysyłany plik również powinieneś być w stanie wygooglować, skoro
taka lama jak ja znalazła i wykorzystuje w programach to chyba każdy powinien dać radę :) Jak coś to pisz.

EDIT: teraz sobie uświadomiłem przed pójściem spać, że nie do końca napisałem prawdę, bo wcale nie musisz
nic zaposywać na dysku. Wygenerowany html z ankietą możesz zapisać do MemoryStreama, po czym możesz
go na przykład spakować ZLibem i wysłać funkcją HttpPostFile - podając jako parametr stream ten własnię już
w pamięci spakowany Stream. Operujesz na strumieniach nic nie zapisując na dysku jezeli to nie jest, a w tym
przypadku akurat - nie jest konieczne. Jak znasz się na php albo znajdziesz coś na ten temat w sieci, to pewnie
da się i tak zmusić skrypt php aby na przykład Delphi generowalo jakieś tokeny w "ciasteczkach" czy coś w tym
stylu a skrypt php to sprawdzał czy też modyfikować UserAgenta. Te kombinacje mają na celu tylko to aby bez
użycia programu ktoś na serwer nie wysłał Tobie błędnych danych. Chociaż nie wiem co tutaj doradzić gydż nie
znam sie na php i zabezpieczeniach. Jednak ostatnio wysyłałem swojego PITa drogą elektroniczną bez podpisu
klwalifikowanego i nie wiem jak sama wysyłka PITa, ale potwierdznie uzyskuje się poprzez pdfa protokołem, z
tego co mi się wydaje, HTTP i Javascriptem no i wystarczające jest sprawdzenie kwoty podatku z poprzedniego
roku oraz wybranie konkretnego urzędu. Dane na pewno słane są w XMLu, jednak podejrzewam że jednak na
tę okazję napisano serwer TCP/IP z ktorym odpowiednimi komunikatami porozumiewają się aplikacje do pitów.
Jednak jeżeli założyć że użytkownikami Twojego progrsmu - ankiety nie będą domorśli h4x0rzy i dziec neo, to
według mnie możesz użyć protokołu HTTP, bo z SSLem czy innymi metodami to więcej kobminacji i w tym nie
za bardzo mogę pomóc, bo też nie znam się na wszystkim. Czasami trzeba mieć do użytkownika ciut zaufania.

0

Wiesz zapisać go na dysku chce bo jak coś ktoś może potem sprawdzić swoje odp. CO DO XML to zaczyna mi się podobać tylko teraz jakie w nim sekcje mogę wykorzystać do budowy ankiety tj mamy pytania i możliwość udzielenia kilku odp ilość pytań jest zmienna wiec program musi pobrać liczbę pytań z XML i przystosować się do niej(czyli jak bo lamą to ja jestem teraz) potem wczytać wszystkie pytania i odp do nich(chętnie wysłucham sugestii do tego myślałem o komponentach label i checkbox ale nie wiem czy to dobry pomysł no i potem jak zebrać z tego info i wpisać do pliku wynikowego?)niektóre pytania mają też formę otwartą więc pasuje jeszcze gdzieś memo dorzucić. Więc kolego widzę że mogę liczyć tylko na Ciebie na forum i tu moja prośba poprowadź "dziecko" za rączkę :/

Plik XML wyglądałby tak:
<Ankieta>
<1pyt>
<pyt>jakieś pytanie</pyt>
<1odp>...</1odp>
<2odp>...</2odp>
<3dop>...</3odp.
</1pyt>
<2pyt>
<pyt>jakieś pytanie</pyt>
<1odp>...</1odp>
<2odp>...</2odp>
<3dop>...</3odp.
</2pyt>
</Ankieta>
itd...
teraz kwestia do jakich komponentów to wczytać żeby miało to wygląd i sens?

0

Ech, leniuszek z Ciebie. Wykorzystujesz moją chęc pomagania w kwestiach w których umiem pomóć. Tylko w
ogóle nie mam pojęcią dlaczego nie skorzystałeś ze źródeł które Tobie wrzuciłem na www. Masz wszystko, co
potrzebne do okiełznania XMLa. W sumie poświęciłem trochę czasu i fakt że wyspałem się w dzień, a w nocy
jakoś lepiej mi się myśli i napisałem taki program jaki jest pod adresem na końcu posta. I jak widać po jego
kodzie źródlowym to nie jest nic skomplikowanego. A tak masz ograniczoną satysfakcję. Chciałeś zrobić sam
program - ankietę, a zrobiono go za Ciebie. Coż, przeanalizuj kod źródlowy. W razie pytań pisz, ale postaraj
się coś samodzielnie napisać. Na przykład używając komponentów Synapse (bardzo wygodnych w obsłudze)
spróbuj zrobić wysyłanie ankiety na serwer www poprzez skrypt php który Tobie pokazałem wcześniej. Myślę
również, że plik xmla trzeba czytać z zasobów a nie z dysku, bo ktoś pozmienia treść pliku i to nie ma sensu.
Jak umieszczać dane w zasobach znajdziesz nawet w artykułach na stronie 4programmers. Co do ankiery, to
ja zrobiłem tak, że po skończeniu odpowiadania na wszystkie pytania można ją zapisać do pliku. Jak widzisz
to inaczej to sobie pozmieniaj w kodzie co chcesz i jak chcesz. Co samego formatu XMLa, to taki plik - jak Ty
podałeś jest nieco bez sensu. Można łatwo się gdzieś pomylić. Ja zastosowałem taki format i imo jest lepszy.
Bo Ty w swoim się pomyliłeś i były literówki, a tutaj trudniej o pomyłkę tylko ważne jest /> na końcu wpisow:

<ankieta>
   <pyt wyborkilku="0" tresc="Tutaj jakieś pytanie numer 1">
      <odp>
      <wariant tresc="Odpowiedź 1"/>
      <wariant tresc="Odpowiedź 2"/>
      <wariant tresc="Odpowiedź 3"/>
      </odp>
   </pyt>   
   <pyt wyborkilku="1" tresc="Tutaj jakieś inne pytanie numer 2">
      <odp>
      <wariant tresc="Jakaś dluższa odpowiedź numer 1"/>
      <wariant tresc="Jakaś inna dluższa odpowiedź numer 2"/>
      <wariant tresc="Jakaś jeszcze inna dluższa odpowiedź numer 3"/>
      </odp>
   </pyt>   
   <pyt wyborkilku="0" tresc="Inne pytanie numer 3">
      <odp>
      <wariant tresc="Jakaś dluższa odpowiedź numer 1"/>
      <wariant tresc="Jakaś inna dluższa odpowiedź numer 2"/>
      <wariant tresc="Jakaś jeszcze inna dluższa odpowiedź numer 3"/>
      </odp>
   </pyt>   
</ankieta>

Słowo wariant możesz zastąpić innym, ale ważne żeby przed "tresc" przy sekcji odp był jakiś wyraz.
Zresztą poeksperymentuj. Program jest po polsku, ale kod poza plikiem XML, jeżeli chodzi o użyte w
nim nazwy stałych, zmiennych, funkcji oraz procedur starałem się jako tako nazywać po angielsku :)
Poniżej link do źródeł. Program może nie jest doskonały, ale działa już od jednego pytania. Zaś do
pytania powinny być według logiki przynajmniej dwie odpowiedzi. Atrybut "wyborkilku" pozwala Tobie
na ustalenie, czy pytanie ma mieć możliwość wybrania więcej niż jedenej odpowiedzi. To ide spać :)
http://www.speedyshare.com/files/21457153/ankieta.rar

0

Możesz nie wierzyć ale to nie kwestia lenistwa porostu nic nie napisałem ani nawet nie myślałem o tym od kilku lat a teraz muszę. Co do XML'a fakt ładnie napisałeś ale żebym to wiedział co do czego dokładniej... :/ muszę odświeżyć pamięć ale to zajmie trochę czasu a tego ta ja nie mam ;(

Jeśli dobrze widzę to tworzysz komponenty dynamicznie i teraz chciałbym zmienić np styl czcionki ale zgłasza mi błąd QLab.Font.Style:=QLab.Font.Style + [fsBold]; dlaczego? Dalej są pytania które mają kilka odp a inne kilkanaście i są ucinane myślę o autosize ale nie mam pomysłu bo do samego QuestionGroup nie ma sensu a do całego okna nie wiem jak no bo QuestionGroup rozciągnąć do ilości pytań a okno do QuestionGroup? Takie nie bardzo mi się widzi ;/ Dalej potrzebuję odać memo lub richedit jako otwarta odp ale ta opcja będzie dostępna tylko przy paru pytaniach tle już chyba łapę jak to zrobić na wzór "wyborkilku" (mogę tak próbować?) Gdzie i co muszę zmienić aby się wyświetlało po więcej niż jednym pytaniu?

0

No ja miałem czas i napisałem w zasadzie większośc programu za Ciebie. Co do formatu XMLa jaki użyłem - to
myślałem, że wszystko jest jasne. Przeanalizuj przykładowy plik. Gałąź głowna (root) o nazwie ankieta - musi
być, bo to podstawa. Później podgałęzie z danymi pytania i odpowiedzi nazywają się pyt. Parametr wybórkilku
określa czy mamy możliwość zaznaczenia tylko jednej odpowiedzi w RadioButtonach (wartość w cudzysłowie w
takim przypadku musi być różna od 1) lub można zaznaczyć wiele odpowiedzi (wartość w cudysłowiu równa 1).
Natomiast odpowiedzi są w gałęzi <odp> podajesz atrybut wariant i ważne po nim słowo tresc i w cudzysłowie
ma być odpowiedź koniecznie zakończona drugim cudzysłowem oraz znakami slash i prawy ostry nawias (/>).
A no i zapomniałem dodać treść pytania jest w gałęzi pyt w atrybucie również o nazwie tresc. Zresztą masz do
kodu załączony przykładowy plik ankieta.xml ktorego używa program, także uważam że wszystko powinno dla
Ciebie być jasne. Jeżeli jednak czegoś jeszcze nie wiesz to pytaj, chociaż jak wspomniałem program, jako taki
masz już właściwie napisany. Jedynie dodać załadowanie xMLa z zasobów w zdarzeniu OnCreate formatki i już.

<pyt wyborkilku="0" tresc="Tutaj jakieś pytanie numer 1">
      <odp>
      <wariant tresc="Odpowiedź 1"/>
      <wariant tresc="Odpowiedź 2"/>
      <wariant tresc="Odpowiedź 3"/>
      </odp>
   </pyt>>
0

Budowę XML'a już trochę poznałem (Google) także rozumiem o co z grubsza chodzi co do wyborkilku to chce to zmienić np na opdowiedzotwarta żeby program zamiast zmieniać radio na check do check'ów dodawał powiedzmy memo (całość jest wielokrotnego wyboru). Doradź coś z tym autosize oraz dlaczego nie chce zaakceptować takiego polecenia odnośnie stylu czcionki.

PS Jak mogę się odwdzięczyć?

0

Nie wiem czy komuś się będzie chciało wypełniać ankietę przez podawanie jakiś informacji w Memo. Ale jak
założyłeś, że tak to zrób dynamicznie tworzenie Memo a nad nim Label z pytaniem. Nikt Tobie nie broni. Co
do kodu jeszcze, bo ślęczałem nad nim w nocy i Delphi sypało mi błędami AV. Te dwa pzyciski- poprzednie
i następne pytanie nie można tworzyć było co pytanie bo nie pozwalały wtedy ustawiać tekstu w Labelu, w
polu edycyjnym tak, ale w Labelu nawet umieszczonym na formatce, a nie dynamicznie - nie. I nie wiem w
ogóle dlaczego, jakiś błąd może Delphi. Dlatego kod jest taki jak widziałeś. Co do niewidocznego Labela o
nazwie TempLabel z opcją Autosize na True, to użyłem go po to aby sprawdzić jak długi będzie tekst, który
chcę później umieścić na CheckBoxach albo na RadioButtonach. Po prostu przypisywałem go najpierw temu
TempLabelowi. Następnie mając jego szerokość po AutoSize czyli jak sam się rozszerzył i dopasował do tej
szerokości tekstu dodawałem 20 pikseli czyli tak na oko szerokośc pola do zaznaczenia i dzięki temu mam
dopasowane rozmiarowo CheckBoxy oraz RadioButtony do odpowiedzi przy okazji ładnie wyśrodkowane. Ale
jak chcesz Memo użyć do wpisywania odpowiedzi to wtedy własnośc Answers musi być raczej tablicą typów
TStringList chyba i to dynamiczną, bo jak w Memo wpiszesz dłuższy tekst niz jedna linia - podzielony przy
użyciu entera, to odpowiedzi najprawdopodobniej "zleją się" wszystkie razem, także trzeba użyć tablicy, ja
przynajmniej tak to widzę. Co do zmiany czcionki to masz własność dla Labelów i większości komopnentów
w stylu Font.Name, Fonr.Size oraz Font.Color - to sobie je ustaw na jakie chcesz. I tak jak pisałem - masz
gotowy kod, możesz sobie przerabiać, ulepszać i zmieniać jak się Tobie podoba, byle by się kompilował, no
i nie pokazywał błędów AV lub innych. Co do odwdzięczenia to jeżeli chcesz się odwdzięczyć będzie mi miło.
Jeżeli jesteś w stanie przelać jakąś sumę na moje konto bankowe albo jak wolisz na PayPala - to mogę na
Twój email wysłać potrzebne dane. Ja chętnie jak jestem w stanie pomagam tutaj, jednak wiele osób tego
nie robi jeżeli jakaś osoba chce napisać program ale nic sama nie stworzyła, bo to można nazwać taka, jak
moja pomoc niestety nie motywuje kogoś aby sam się uczył pisać program jaki potrzebuje, a nawet jak nie
ma na to za wiele wolnego czasu to dostając gotowca, nie motywuje go do znalezienia tego czasu by sam
coś napisać. Mam nadzieję, że Ty nie spoczniesz na laurach i sobie dalej sam poradzisz. Ale jak coś - pisz.

EDIT: co do przechowywania wielu łuższych odpowiedzi wprowadzanych do Memo, to nie trzrba koniecznie
używać tablicy dynamicznej TStirngList. Można na obiekcie typu TList przechowywać do nich wskażniki, a
co to wskaźniki to sobie poczytaj. Poniższy kod Tobie może podpowiedzieć jak przechowywać te dane, jak
chcesz zobaczyć jak to działa, chociaż już w moim programie widziałeś jak działa obiekt typu TList - to na
formatce o nazwie Form1 najlepiej w nowym projekcie umieść Memo1, LisrBox1 oraz Button1 i podczep im
następujący kod to znaczy OnCreate dla formatki, dla przycisku OnClick oraz OnClick dla ListBoxa, w razie
pytan pisz, ale wszystko powinno być jasne. W sumie w Delphi 7 i nawet nieco wcześniejszych można do
przechowywania wielu takich samych typów używać tablicy dynamicznej, ale dla obiektu niewizualnego to
równie dobrze - jak i wizualnego - używac obiektu TList. Tylko należy pamiętać aby nie zwalniać po tym
jak dodasz obiekt do TList, bo wskaźnik po prostu nie będzie na nic wkazywał i otrzymasz błąd AV - czyli
jak widzisz w kodzie poniżej nie ma nigdzie SL.Free. Przeanalizuj go sobie to będziesz wiedział o co chodzi.

//...
  public
    ListOfSL : TList;
    SL : TStringList;
  end;

var
  Form1 : TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListOfSL := TList.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SL := TStringList.Create;
  SL.Text := Memo1.Text;
  ListOfSL.Add(SL);
  ListBox1.Items.Add(IntToStr(ListOfSL.Count));
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  if ListBox1.ItemIndex > -1 then
  begin
    ShowMessage(TStringList(ListOfSL[ListBox1.ItemIndex]).Text);
  end;
end;
0

Kolego olesio proszę o kontakt gg 12095255 mam pare pytań odnośnie kou i mojej korekty jego tzn mam kłopot w kilku miejscach (głównie z podpięciem się do twojego kodu... ;()

0

Ech, gotowca dostałeś do niewielkich zmian i nadal masz problemy.
Napisałem na GG do Ciebie. Coś za dobry jestem dla leniuchów ;/

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