[vb6] MSHFLEXGRID, przenoszenie między tabelami

Oczywiście, że patrzyłem. Plik dobry choć też przy otwieraniu w mojej bazie Access coś tam naprawiało.

Największy jednak problem to fakt, że w Twoim programie całkiem inaczej współpracują kontrolki Adocd1 i MSHFlexGrid1 z bazą Access

Jeżeli klikniesz na tabelkę MSHFlexGrid1 i  w oknie Properties zerkniesz na właściwości tej kontrolki, to jest tam tak właściwość jak:

DataSource i jej wartość= Adocd1. Z wykorzystaniem tej właściwości dane są pobierane z bazy Access i wpisywane do tabelki.

Nie trzeba wówczas niż więcej wpisywać. Niestety już dawno zauważyłem, że z wykorzystaniem tej właściwości coś kiepsko program działa i pojawiają się rożne kłopotliwe sytuacje.

Z tego właśnie powodu ja nie korzystam z tej właściwości i całą obsługę pobierania danych z bazy Access i wpisywania do tabelki sam napisałem. Trochę ,to kłopotliwe, ale przynajmniej działa jak należy.

Ciekawe jak u Ciebie działa drukowanie w tym do pliku pdf, drukarkę, czy tworzenie pliku Excela. U mnie działa wszystko poprawnie.

Jedyną wadą tego drukowana jest, to, że użytkownik musi mieć zainstalowany Excel oraz przynajmniej AdobeReadr czy też PDFcreator i ewentualnie drukarkę.

No i jeszcze trzeba dołączyć odpowiednie biblioteki: Project–>References gdziedolącazmy obslugę Excela czy PdFCreator.

Taka jeszcze uwaga: jeżeli tworzysz jakieś plik z danymi to dawaj też rozszerzenia do tych plików. jeżeli to plik tekstowy, to np. dane.txt albo dane.dat.

Jeżeli plik nie ma rozszerzenia, to wygląda kiepsko, a jakiś program czyszczący może go usunąć traktując go jako śmieć.

Czyli teraz już rozumiem na przyszłość nie będę korzystał z tej właściwości datasource=adodc1 można tylko narobić sobie problemów. Jeszcze próbuję ustawić żeby przyciski usuń oraz przenieś działały tylko wtedy jak zaznaczony jest jakiś element w mshflexgrid1 bo teraz działa tak że jeśli nic nie jest zaznaczone to kasuje(przenosi) ostatni wiersz z siatki.

Po głowie chodzą mi jeszcze dwa tematy:

1.Czy mogę przenosić elementy z tabeli do tabeli edytując ostatnią kolumnę? Miało by to wyglądać tak: wybieram z siatki mshflexgrid1 wiersz który chce przenieść naciskam button otwiera mi się forma na której są textboxy(zablokowane do edycji) i jeden combobox w którym wyświetlone są  wszystkie możliwe opcje zmiany (można tylko raz wybrać  jedną z opcji, przy próbie przeniesienia kolejnego wiersza w combo ta opcja która była użyta wcześniej już nie widnieje.

  1. Do wyświetlania ilości wierszy użyłeś Label4.Caption = MSHFlexGrid1.Rows - 1 , zlicza ona ilość wierszy tylko wtedy jak jest wlączona forma z siatka msh. Czy można zliczać wiersze w innej form1 bez konieczności włączania formy z mshflexgrid1, jeśli chce przenosić wiersz z tabeli do tabeli bez włączania formy z mshlexgrid??

Rzeczywiście z tym usuwaniem było trochę nie intuicyjnie. Teraz zmieniłem i domyślnie zaznaczany jest pierwszy wiersz do usuwania.

Usunąłem też formę do edycji i teraz wszystko jest robione na głównej formie.

  1. Pewnie da się zrobić, ale tak to opisałeś bardzo ogólnie, że nie za bardzo wiem o co chodzi.

  2. Jeżeli chcemy się odwoływać z jednej formy do obiektów na innej formie, to jest to możliwe.

np. Jeżeli jesteśmy na formie1 a tabela jest na formie2

  LiczbaWierszy= forma2.MSHFlexGrid1.Rows

zmiana koloru tła wiersza stałego:

MSHFlexGrid1.BackColorFixed = &HFFE468

Ustawienia koru zaznaczenia

MSHFlexGrid1.selectionmode=1

 Jeśli przenoszę jeden cały wiersz do drugiej tabeli czy mogę edytować ostatnią jego wartość??

 

Już trochę na niej pracowałem też jest ciekawa ale msh ma przewagę graficzną nad datagrid co jest bardziej przyjemne dla oka

 

 

 O to właśnie mi chodziło :slight_smile:

 

a czy mshflexgrid może mieć taką funkcjonalność że dopóki nie wybiorę na siatce jakieś komórki to nie będzie aktywny button??

 

 

 

1)Oczywiście, że można np.

Przy ładowaniu formy (zdarzenie: Form_Load()) ustawiamy buttonom cechę enabled na false

Command2.Enabled = false: Command3.Enabled = false: Command5.Enabled = false

a po kliknięciu na tabelę(zdarzenie: MSHFlexGrid1_click()) zmieniamy na true.

Command2.Enabled = True: Command3.Enabled = True: Command5.Enabled = True

2)Edycja ostatatniej wartości wiersza?

tekst=MSHFlexGrid1.TextMatrix(MSHFlexGrid1.row, 7)

i zmienną tekst wpisujesz gdzie Ci pasuje.

Żeby teksty w tabeli prezentowały się elegancko, to jeszcze przykład jak te teksty ustawić do prawej strony(np.liczby) lub wyśrodkowane (np. daty).

Wpisać przy ładowaniu formy (zdarzenie Form_Load()):

MSHFlexGrid1.ColAlignmentFixed = 3

MSHFlexGrid1.ColAlignment(3) = 3

MSHFlexGrid1.ColAlignment(7) = 3

MSHFlexGrid1.ColAlignment(5) = 6

MSHFlexGrid1.ColAlignment(6) = 6

 

 

Chciałem zrobić żeby za pomocą buttona przenosić cały wiersz do innej tabeli. Cała trudność w tym że  miało to by wyglądać następująca:Mam 4 tabele, 1 główa z wszystkimi wpisami(baza główna),2 tabela (narzędzia) z której będę przenosił dane do tabeli 3(nowe) albo tabeli 4(stare) albo z powrotem do tabeli 2(narzedzia).Dane przy wprowadzaniu będą zapisywały się w tabeli 1 i w tabeli 2 W czym tabela 1 jest tylko zbiorem wszystkich wpisów ale miała by się aktualizować przy zmianach wartości w MSHFlexGrid1.row, 7 przy przenoszeniu wierszy międzi tabelami 2 ,3 i 4 . Klikam w tabeli 2 (na formie znajdują się 2 buttony do ktorych przypisana jest możliwość przeniesienia wiersza do jednej z tabel 3 albo 4) na interesujący mnie wiersz który chce przenieść i zatwierdzam buttonem opowiedzialnym za przeniesienie wiersza do tabeli 3(nowe), wiersz ładuje się do nowej formy w której jest odpowiednia ilość textboxów i jeden combo . W combo jest jedyna możliwość edycji ( z MSHFlexGrid1.row, 7)combo ładuje się z base.mdb(wartości np. 10,20,30,40,50) wybieram wartość 20 i zapisuje buttonem(wiersz został przeniesiony z tabeli 2 do 3 a jego wartość w tabeli 1 MSHFlexGrid1.row, 7 została zmieniona na “20”) . Przy próbie przeniesienia następnego wiersza z tabeli 2( narzędzia) do 3 (nowe) combo wyświetla mi już tylko wartości 10,30,40,50 do momentu kiedy wiersza z powrotem nie przeniosę do tabeli 2(narzędzia).

Hmmm tak się zastanawiam czy opisałem to w miarę zrozumiale :wink:

 

 

 

Wiem już jak ładować dane do jednego comboboxa, a w jaki sposób załadować następujące dane zależne od siebie, mam 4 pliki  txt i dwa comboboxy.

np.

Typ.txt  i    combi .txt      sedan.txt     sport.txt

 

W pliku Typ.txt znajdują się dane

combi

sedan

sport

Typ.txt ładowany jest do combo1 i w zależności którą opcje wybiorę z rozwijanej listy taki plik z danymi załaduje mi się do combo2.

Może lepszym rozwiązaniem było by żeby dane nie czytały się również z *.mdb jeśli jest taka możliwośc.

 

 

 

 

 

 

 

W pliku

Całego programu nie będę Ci rozpisywał bo Ty byś się nudził.

Tabele umiesz tworzyć, przysyłanie do tabel też.

Jak zrozumiałem jedyny kłopot to przesyłanie danych z jednego combo do drugiego.

Dane można pobierać z okna tekstowego, tabeli czy też z pliku tekstowego.

Dla przykładu podaję chyba ciekawsze rozwiązanie gdy dane będą pobierane z pliku tekstowego.

  1. Tworzymy w notatniku trzy pliki tekstowe i zapisujemy  pod nazwami combo.txt, tekst0.txt, tekst1.txt, tekst2.txt

W pliku combo.txt umieszczamy tekst:

strony1

strony2

strony3

w pliku tekst0.txt wpisujemy:

http://onet.pl

http://wp.pl

w pliku tekst1.txt wpisujemy:

http://interia.pl

http://www.dobreprogramy.pl

w pliku tekst2.txt wpisujemy:

http://tv-trwam.pl/na-zywo

http://www.5fantastic.pl/plikosfera

  1. Na formie umieszczamy dwa obiekty combo:

combo1 i combo2

  1. Globalnie deklarujemy:

    Option Explicit
    Private Declare Function ShellExecute Lib “shell32.dll” Alias “ShellExecuteA” _
    (ByVal Hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
    ByVal lpParameters As String, ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long

  2. W formie (zdarzenie load) wpisujemy:

    Private Sub Form_Load()
    Dim ff As Long
    Dim line As String
    ff = FreeFile
    Open App.Path & “\combo.txt” For Input As #ff
    Do While Not EOF(ff)
    Line Input #ff, line
    Combo1.AddItem line
    Loop
    Close #ff
    Combo1.ListIndex = 0
    End Sub

  3. W  combo1(zdarzenie click) wpisujemy:

    Private Sub Combo1_Click()
    Dim i As Integer
    Combo2.Clear
    i = Combo1.ListIndex
    Dim ff As Long
    Dim line As String
    Dim adres As String, tekst As String
    adres = “\tekst” + CStr(i) + ".txt"
    ff = FreeFile
    Open App.Path & adres For Input As #ff
    Do While Not EOF(ff)
    Line Input #ff, line
    Combo2.AddItem line
    Loop
    Close #ff
    Combo2.Text = "wybierz"
    End Sub

6)W  combo2(zdarzenie click) wpisujemy:

Private Sub Combo2_Click()
Dim x As Integer
Dim adres As String
adres = Combo2.List(Combo2.ListIndex)
x = ShellExecute(Hwnd, "Open", adres, &O0, &O0, 1)
End Sub

I już można program uruchomić obserwując efekty jego działania.

W poprzednim poście napisałem dwa pytania które dotyczyły całkiem czego innego . Jedno było odnośnie przenoszenia w tabelach z zmianą ostatniej wartości w wierszu a drugie zależności między comboboxami.

Pozwoliłem sobie na Twoja skrzynkę wysłać plik .txt, czy w takiej postaci plik który Ci wysłałem można załadować do vb, textboxów  każda jedna wartość do innego okna??Plik otwieram przez notepad++ jest bardziej czytelny.

W Windowsie koniec linii w tekście składa się  z dwóch znaków: chr(13) & chr(10)

Tekst który przesłałeś

SQL> Select c.dest_id SKLEP, m.trailer_id NACZEPA,m.door_id RAMPA from container c inner join container_item ci on c.facility_id=ci.facility_id
  2 and c.container_id=ci.container_id left outer join manifest m on c.facility_id=m.facility_id and c.bol_nbr=m.bol_nbr where c.facility_id='TE'
  3 and c.container_status in ('M') and c.dest_id in ('34297') group by m.trailer_id, m.door_id, c.dest_id order by m.trailer_id, m.door_id, c.dest_id;

SKLEP NACZEPA RAMP                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
---------- ------------ ----                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
34297 SPOT106 106                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             

SQL> spool off

jest zapisany w systemie Unix(linux) w kórym koniec linii jest kodem znaku liczby 10: chr(10)

i w Windowsie jest widoczny jako jedna linia.

Przy podziale tego tekstu na linie trzeba to uwzględnić.

W tym przypadku tych linii będzie siedem i trzeba przygotować 7 okienek tekstowych aby zapisać każdą linię w innym okienku.

Dim ZnakKoncaLiniiWindows As String
Dim ZnakKoncaLiniiUnix As String
ZnakKoncaLiniiWindows = Chr(13) + Chr(10): ZnakKoncaLiniiUnix = Chr(10)
Dim Tekst As String
Dim ff As Long
Dim j As Long, i As Long
Dim tablica() As String
Dim LiczbaWierszy As Long
   ff = FreeFile
   Open App.Path & "\dane.txt" For Input As #ff
   Tekst = Input$(LOF(ff), ff)
   Close #ff
   tablica = Split(Tekst, ZnakKoncaLiniiUnix)
   LiczbaWierszy = UBound(tablica): Tekst = ""
   For j = 0 To LiczbaWierszy - 1
   If tablica(j) <> "" Then
   Tekst = Tekst & tablica(j) & ZnakKoncaLiniiWindows
   Text2(i).Text = tablica(j)
   i = i + 1
   End If
   Next j
   Open App.Path & "\danenowy.txt" For Output As #ff
   Print #ff, Tekst
   Close #ff
   Text1.Text = Tekst

aby tylko przetworzyć taki tekst pod Windows wystarczy użyć takiej procedury:

Dim ZnakKoncaLiniiWindows As String
Dim ZnakKoncaLiniiUnix As String
ZnakKoncaLiniiWindows = Chr(13) + Chr(10): ZnakKoncaLiniiUnix = Chr(10)
Dim Tekst As String
Dim ff As Long
Dim LiczbaWierszy As Long
   ff = FreeFile
   Open App.Path & "\dane.txt" For Input As #ff
   Tekst = Input$(LOF(ff), ff)
   Close #ff
   Tekst = Replace(Tekst, ZnakKoncaLiniiUnix, ZnakKoncaLiniiWindows)
   Open App.Path & "\danenowy.txt" For Output As #ff
   Print #ff, Tekst
   Close #ff

i jeszcze procedura wskazania ostatniego elementu z okna tekstowego złożonego z wielu linii i zakończonego znakiem końca linii. (Jeżeli tekst nie będzie zakończony znakiem końca linii to Text2.Text = tablica(Gzakres ))

Dim ZnakKoncaLiniiWindows As String
Dim Tekst As String
ZnakKoncaLiniiWindows = Chr(13) + Chr(10)
Dim tablica() As String
Dim Gzakres As Long
  Tekst = Text1.Text
  tablica = Split(Tekst, ZnakKoncaLiniiWindows)
  Gzakres = UBound(tablica)
  Text2.Text = tablica(Gzakres - 1)

Podałeś mi żeby odczytać wszystkie linie a jesli mnie interesuje tylko linia z winikami zapytania czyli :

34297 SPOT106 106 i te dane umieścić w 3 osobnych texboxach?

Zbyt niejasno stawiasz pytania, a potem się dziwisz. W tym pliku który podałeś, to interesująca cię linia jest przedostatnia, a nie ostatnia (jeśli nie weźmie się pod uwagę pustych linii).

Ta procedura daje wynik o jaki Ci chodzi.

Dim ZnakKoncaLiniiUnix As String
Dim Tekst As String
Dim ff As Long
Dim i As Long
Dim tablica() As String
Dim GwymiarTablicy As Long
   ZnakKoncaLiniiUnix = Chr(10)'=chr(13) & chr(10)dla plików utworzonych w Windows'
   ff = FreeFile
   Open App.Path & "\dane.txt" For Input As #ff
   Tekst = Input$(LOF(ff), ff)
   Close #ff
   Tekst = Replace(Tekst, ZnakKoncaLiniiUnix & ZnakKoncaLiniiUnix, ZnakKoncaLiniiUnix)
   tablica = Split(Tekst, ZnakKoncaLiniiUnix)
   GwymiarTablicy = UBound(tablica)
   Tekst = Trim(tablica(GwymiarTablicy - 2))
   Tekst = Replace(Tekst, " ", " "): Tekst = Replace(Tekst, " ", " ")
   tablica = Split(Tekst, " ")
   For i = 0 To 2: Text2(i).text = tablica(i): Next i

Procedura będzie dawała dobry wynik dla innych takich plików, ale gdy interesujący Cię tekst będzie zawsze w przedostatniej linii w przeciwnym przypadku, to procedura musiała by być bardziej rozbudowana.

Sorry mój błąd, tak analizuje ten kod i jak na razie nie wiem co jest do czego :slight_smile: sporo nowych rzeczy a to pewnie dopiero wierzchołek góry lodowej :slight_smile:

Może przydatne linki:

http://www.vb4all.pl/teoria/iso2/wstep.htm

http://matrix.ur.krakow.pl/~aborowiecki/VB/VBW/progr%20VB.pdf

http://edu.pjwstk.edu.pl/wyklady/rbd/scb/wyklad9/sql.htm

 

Dzięki za linki na pewno z nich skorzystam :slight_smile:

Ale w czym problem bo listboxy to takie tabele tylko z jedną kolumną.

Stworzyłem dwie tablie listbox w pierwszej mam dane z pliku combo natomiast w drugim listboxie odczytywane są dane zawarte w w tekst1.txt oraz tekst2,txt w zależności co wybiorę w pierwszym listboxie. Combo (listobx1) dodaje i usuwam bez problemu , natomiast kłopot pojawia się w drugim listbox z dodaniem u usunięciem jakiejś pozycji, żeby dane zapisywały się i usuwały z odpowiedniego pliku txt który aktualnie jest wyświetlany w listbox2 . Czy vb umożliwia przekonwertowanie znaku “.” na “,” np. 1.5 na 1 ,5??

zapis 1,5 dla vb zawsze oznacza tekst, a nie liczbę.

Jeżeli liczbę umieszczamy w oknie tekstowym, tabeli, liście itd, to automatycznie zostanie zapisana jako tekst w postaci takiej jak ustalone to jest w Windowsie czyli w oknie będziemy widzieć 1,5

Np.

dim x as single

x=1.5

text1.tekst=x

Zobaczymy napis:“1,5” i to już jest tekst, a sama zmiana zapisu dokonuje się automatycznie.

Czasami zachodzi potrzeba aby z zapisu tekstowego odczytać jaka to liczba.

np w listboxie mamy wiersz: “1,5” wówczas przecinek musimy zamienić na kropkę funkcją ‘replace’ i funkcją ‘val’ zapisać ją do do zmiennej liczbowej.

zmienna x musi być zadeklarowana jako liczba wymierna (single), a nie całkowita (integer).

Dim  x As Single

x = Val(Replace(List1.List(List1.ListIndex), “,”, “.”))

Może się też zdarzyć, że w pliku tekstowym będzie zapisana liczba w postaci “1.5”, to jeśli dodamy ten tekst do listy, to też będzie zapisany w postaci “1.5”

Zamienić ten tekst na liczbę można  funkcją val: 

dim as single

x=val(List1.List(List1.ListIndex))

A jeżeli tylko chcemy zamienić ten tekst na postać z przecinkiem zamiast kropki to używamy funkcji replace.

dim pom as string

pom=Replace(List1.List(List1.ListIndex), “.”, “,”)

Ja mam taki przypadek tylko ze chce odczytac w label, do tego jeszcze chce zrobić petle zeby sprawdzała pozostałe label czy jest w niej wpisana jakas wartość(wprowadzana jest z pliku tekstowego) jesli jest tak to zamien “.” na “,” . Potrzebna  jest  mi cyfra bo w dalszej części kodu będę robił obliczenia.

 

ukleciłem coś takiego ale cos z tymi label pomyliłem

Dim i As Single

For i = 0 To 12

Text6(i) = Val(Label6(i))

Next i

Litera “i” jest tutaj liczbą całkowitą i zmienia się od zera do dwunastu.

text6(i).text to jest przecież okno tekstowe i nie ma sensu pisaćtext6(i).text= val(label6(i).caption bo napis też jest tekstem.

powinno być:

Dim i As Single

For i = 0 To 12

Text6(6).text = Label6(i).caption

Next i

Odczytanie jakiegokolwiek napisu z każdego okna będzie zawsze tekstem.

Tylko taka zmienna może być liczbą którą zadeklarujemy jak liczbę.

Dim i As integer

dim  liczba(12) as single

For i = 0 To 12

Text6(i).text = label6(i).caption

liczba(i)=val(Text6(i).text)

next i

Wyniki będą prawidłowe jeżeli napisy w oknach tekstowych będą miały kropkę, a nie przecinek między częścią całkowitą i ułamkową.

Na liczbach można wykonywać dzialania.Jeżeli np. liczba(0)=1.2, liczba(1)=1.5

dim x as single

x=liczba(0)+liczba(1)  to x =2.7

Dodawanie tekstów, to jest ich łączenie.

dim tekst as string

text6(0).text=“1.2”: text6(1).text=“1.5”

tekst=text6(0).text+text6(1).text

tekst=“1.21.5”

chodzi tak jak powinno :slight_smile:

a Co z tymi combo co pisałem wcześniej??