Wypowiedzi
-
My tu raczej uprawiamy wolną twórczość, bo autorka nie podała z czego i co importuje;)
-
Wojciech Gardziński:
Bardzo proszę zrobić taki kejsik:
Ma Pani 3 taki pliczki tekstowe, oznaczone PlikTeksowy1.txt itd. (takie jak wyżej)
Zadanie:
Skleić je do kupki, dodać atrybut numeru pliku i pokazać lub wysłać obojętnie gdzie, do Excela może być.
A potem zmienić folder, najlepiej parametrycznie, i zrobić to samo (może być w inne miejsce lub po prostu do arkusza) z plikami o numerach 4,5,6 z tego drugiego folderu
Najpierw pokaże Pani swoje rozwiązanie, a potem ja moje, OK?
Podejmę rękawice, jak rycerz w zastępstwie Moniki;)
Tylko zmieniam zasady, trzymajmy się pytania źródłowego:
Czyli importu do tabeli access'a
Założenia
znamy strukturę pliku, znamy katalogi ale nie wiemy jakie są nazwy plików
i ile ich jest
Zadanie
Zaimportować pliki tak że w każdej tabeli będą pliki z jednego katalogu dodając kolumne idpliku z nazwą pliku importowanego
Rozwiązanie moje:
Sub PrzetworzTXT(ByVal sciezka As String)
Dim plik As String
Dim katalog() As String
Dim i As Integer
Dim createtab As Boolean
Dim sql As String
Dim schemaini As String
schemaini = "[plik]" & vbNewLine & _
"ColNameHeader = False" & vbNewLine & _
"Format=Delimited(|)"
katalog = Split(sciezka, ";")
For i = 0 To UBound(katalog)
On Error Resume Next
DoCmd.RunSQL "drop table tab" & i
On Error GoTo 0
createtab = True
plik = Dir$(katalog(i) & "*.txt")
Do Until Len(plik) = 0
Debug.Print plik
Open katalog(i) & "schema.ini" For Append As #1
Print #1, Replace(schemaini, "plik", plik)
Close #1
If createtab Then
createtab = False
sql = "SELECT """ & plik & """ as IDPliku, F2 As Pole1,F3 as Pole2,F4 as Pole3,F5 as Pole4,cdbl(Replace(F6,""."","""")) as Pole5" & _
" into tab" & i & _
" FROM [Text;DATABASE=" & katalog(i) & "]." & plik & _
" where len(f6)>0"
Else
sql = "insert into tab" & i & _
" SELECT """ & plik & """ as IDPliku, F2 As Pole1,F3 as Pole2,F4 as Pole3,F5 as Pole4,cdbl(Replace(F6,""."","""")) as Pole5" & _
" FROM [Text;DATABASE=" & katalog(i) & "]." & plik & _
" where len(f6)>0"
End If
Debug.Print sql
DoCmd.RunSQL sql
Kill katalog(i) & "schema.ini"
plik = Dir()
Loop
Next
End Sub
użycie:
PrzetworzTXT "d:\devproject\temp\1\;d:\devproject\temp\2\"
===============================================
Znając życie nikt nikomu nic nie udowodni, ale zabawa przednia ;)Michał Dziubek edytował(a) ten post dnia 05.10.11 o godzinie 13:23 -
Joanna Jemioł:
Witam,
Mam małe pytanko co do kwerendy wyszukującej duplikaty.
Jest dana tabela złożona z ponad 2 mln wierszy, chcę znaleźć rekordy po numerze klienta, w których mogą pojawić się różnice dotyczące danego klienta. Z tabeli wybieram tylko część danych dotyczących klientów.
Co znaczy, że wybierasz część klientów?
Jednak, gdy w postępuję tak, że w pierwszej kolejności stworzę kwerendę grupującą dane według ID klienta, miasta, ulicy, segmentu, waluty, a następnie z niej tworzę kwerendę wyszukującą duplikaty tylko po ID( w wyniku otrzymuję nr ID i ilość wystąpień tego ID) otrzymuję inny wynik niż w przypadku, gdy z wyjściowej tabeli(bez grupowania) tworzę kwerendę wyszukującą duplikaty, która również w wyniku wyświetla nr ID i ilość powtórzeń tego ID - ale wyświetla się znacznie więcej wierszy wynikowych.
Nie bardzo rozumiem czemu szukasz duplikatów w pogrupowanych danych, jeżeli
zakładamy że w uproszczeniu chcesz szukać danych zduplikowanych na takiej tabeli:
id |A |B |
-------------------
1 |a |c
1 |a |c
1 |b |c
1 |c |c
To wynik zapytania:
select
id
,a
,b
from
tabela
group by
id
,a
,b
da wynik
id |A |B |
-------------------
1 |a |c
1 |b |c
1 |c |c
i teraz
kwerenda wyszukująca duplikaty dla id da ci ilość 4 dla całej tabeli i 3 dla kwerendy powyżej.
Podejrzewam, że kwerenda wyszukująca duplikaty działa jakoś inaczej na całej tabeli niż na kwerendzie z pogrupowanymi danymi.
Proszę o pomoc w wyjaśnieniu tej kwestii, nie wiem dlaczego tak się dzieje:(
Reasumując w kwerendzie szukającej duplikaty definiujesz wg. jakich pól szukać tych duplikatów, Ty natomiast pozbawiasz się ich części, przez grupowanie.Michał Dziubek edytował(a) ten post dnia 04.10.11 o godzinie 23:01 -
Aby mieć możliwość przeczytania tego posta musisz być członkiem grupy Access VBA
-
Aby mieć możliwość przeczytania tego posta musisz być członkiem grupy Access VBA
-
Aby mieć możliwość przeczytania tego posta musisz być członkiem grupy Access VBA
-
Aby mieć możliwość przeczytania tego posta musisz być członkiem grupy Access VBA
-
Nie mam doświadczenia z bazami FoxPro, ale może analogicznie do dbf-a jeżeli jest pole typu nota to dbf tworzy plik o rozszerzeniu dbt, może tego brakuje...
A z drugiej strony jaki typ to pole ma zdefiniowanie chodzi mi o typ FoxPro - może wtedy łatwiej będzie wygooglować rozwiązanie -
Paweł Boguszewski:
CO robię nie tak ?
Do otwarcia potrzeba obiektu connection
zmiana w kodzie:
Public rst As ADODB.Recordset
Public con as ADODB.Connection
Function Connect_dbf()
Dim strDBF As String
strDBF = "DSN=Visual Foxpro Database;" & _
"SourceType=DBC;" & _
"SourceDB=C:\trans.DBC;" & _
"Exclusive=No"
Set rst = New ADODB.Recordset
Set con = New ADODB.connection
con.open strDBD
Debug.Print strDBF
With rst
.Open "test.dbf", con
If Not (.EOF And .BOF) Then
Debug.Print rst.Fields(1)
End If
.Close
End With
Set rst = Nothing
con.close
set con = Nothing
End Function
-
Wojciech Gardziński:
To obojętne - patrz dalej.A w czym PROŚCIEJ uruchamiać SQLki?
W oknie kwerendy Access-a, a najprzyjemniej to w ssms;)
Wiem, chodzi mi tylko o to, ze najczęściej używam narzędzi sql-server-a i te mi najbardziej odpowiadają;)
Nie, to dokładnie to samo rozwiązanie. Tylko ja omijam stosowanie schema.ini, bo tam ie da rady np. wersjonować plików. Tak, czy inaczej, gratuluję znajomości tematu.
Aby sprostować, omija Pan faktycznie tworzenie fizycznie schema.ini, ale faktycznie sterownik Microsoft Text Driver wykorzystuje domyślne wartości
z rejestru, schema.ini to nic innego jak (upraszczając) nadpisanie domyślnych ustawień sterownika textowego w systemie
A czy to uruchamiane z Accessa, Excela, czy czegokolwiek innego - to nie ma żadnego znaczenia.
Może Pan to robić z Accessa - byle SQLem, a nie tak, jak Pan na początku... importowaniem danych do tabelek procedurą importową Accessa, bo to jest złe rozwiązanie i to sprowokowało mnie do tej dyskusji.
Ja wiem czy procedury importowe access-a są złym rozwiązaniem, wg. mnie dla szybkich importów ad hoc sprawdzają się świetnie. No i kreator pozwala odczarować tę magię importu;)
Natomiast co do uruchomienia tego z poziomu Access-a czy Excel'a to pytajaca chciała to importować do Access-a, Excel pojawił się dopiero w Pana wypowiedziach, czy rzeczywiście jest to używane dalej i do czego, tego się nie dowiedzieliśmy. -
Wojciech Gardziński:
A w czym PROŚCIEJ uruchamiać SQLki?
W oknie kwerendy Access-a, a najprzyjemniej to w ssms;)
A teraz, porównanie prędkości:
SQL jest ok 10-100 razy szybszy w odczycie takich danych, niż linia-po-linii przez VBA. I się nie wywala.
Wiem, iteracja to nie najwydajniejsze rozwiązanie
Ale, Pan powie, że analitycy o VBA słyszeli, a o SQLu nie.
No, dobra, 2:1 .
Nie nie powiem tak, ale jak Pan tak chce koniecznie SQL-a do tego zaprząc
to rozwiązanie numer 4:
Założenia:
plik nazywa się: test.txt
interesuje nas to co jest pomiędzy znakami: |
Struktura pliku wygląda tak jak w załączonym przez Pana linku:
http://afin.net/excel/PlikTekstowy.txt
Rozwiązanie 4:
1. W katalogu gdzie jest plik test.txt, tworzymy plik schema.ini i wpisujemy do niego:
[test.txt]
ColNameHeader=False
Format=Delimited(|)
2. W Accessie tworzymy nową kwerendę i przechodzimy do widoku SQL.
Wpisujemy następujące zapytanie:
SELECT
F2 as Pole1
,F3 as Pole2
,F4 as Pole3
,F5 as Pole4
,cdbl(Replace(F6,".","")) as Pole5
FROM
[Text;DATABASE=d:\devproject\main].test.txt
where
len(f6)>0
Oczywiście podmieniamy ścieżkę d:\devproject\main na tą gdzie znajdują się pliki. Pominę już czy bezpośrednio w tej kwerendzie zrobimy insert into czy użyjemy tej do stworzenia nowej...
Pozdrawiam
[OFF MODE]
Panie Wojciechu po Pana pierwszej odpowiedzi poświeciłem wieczór na zapoznanie się z Pana strona i blogiem. Uważam że jest Pan "zakodowany" na Excela, tylko nie zawsze trzeba go pchać na siłę tam gdzie można się bez niego obejść.
Ja osobiście zawodowo nie jestem związany w żaden sposób z BI, wykorzystuje Accessa-a i Excela zależnie od potrzeb.
[/OFF MODE] -
Bernarda Gadomska:
Niemniej jednak jak przyda się na pewno informacja jak usunąć wszystkie te linie bez ingerencji w pliki źródłowe.
Możliwości są dwie
1. za pomocą vba zrobić kopię pliku, czytając linia po linii i nie kopiując linii nie spełniających kryteriów, zaimportować dane z stworzonego pliku
2. czytać linia po lini i od razu dodawać do tabeli docelowej
lub alternatywne rozwiązanie zaproponowane przez Pana Wojciecha, chociaż uważam, że niepotrzebne jest tu zaprzęganie excela do tej operacji + autor tego rozwiązania założył, że szerokość pól w tabeli jest stała -
Wojciech Gardziński:
To bardzo proszę odczytać takie coś tą metodą.
http://afin.net/excel/PlikTekstowy.txt
Oczywiście, że się nie da, ta metoda służy do importu plików csv, autorka nie wspomina o liniach niestandardowych csv itd. jedyny problem jaki napotkała to wg. jej opisu separator pól.
Więc poczekamy jak sytuacja się rozwinie... -
W imporcie wybierasz plik z danymi txt, później przechodzisz kreatora w którym wskazujesz że separatorem pól jest | i tyle
-
DLookUp(“[nzwa]”,”[nazwy_klient]”,”[nazwy_klient]![numer] =’”&[tabela].[nr_klienta]&”’”)
To powinno zadziałać, rozważ jednak użycie joina rozwiązanie zdecydowanie bardziej wydajniejsze -
Nie da się zrobić kwerendy krzyżowej w adp, bo jak wiesz silnik JET jest pominięty, skoro to sql 2000 to masz dwa wyjścia:
1. Stworzyć sztucznie namiastkę pivota czyli mniej wiecej tak:
select
kolumnawiersza as costam
,sum(case when klumnakolumny = 'a' then kolumnadosumowania else 0 end) as [A]
,sum(case when klumnakolumny = 'b' then kolumnadosumowania else 0 end) as [B] itd..
from
tabela
group by
kolumnawiersza
2.
a.Za pomocą ADOX catalog stworzyć tempowy plik mdb
b.stowrzyć kwerende przekazującą dane z danymi do tabeli przestawnej
wariant I:
użyć kwerendy z pkt b. do pivota
wariant II:
c. skopiować dane z kwerendy z pkt b.
Select * into tabela from kwerendaprzekazujacadane
d. stworzyc kwerende krzyżową na podstawie tabeli z pkt c.
Ja używam osobiście obejścia 2 z wariantem IIMichał Dziubek edytował(a) ten post dnia 29.09.11 o godzinie 16:33 -
Efekt jest tego taki, że albo wybieramy interakcje formularza zależenie od parametrów, albo dla każdej interakcji osobny formularz.
Różnica jest taka, że w pierwszym przypadku trzeba poświęcić trochę więcej czasu na rozwiązanie, ale można wtedy użyć kodu wielokrotnie.
W przypadku 2 lub więcej formularzy trzeba powielać swoją pracę, a i tak gdzieś w kodzie trzeba sprawdzić który z nich otworzyć.
Wybór zależy od preferencji/umiejętności autora. Tak jak pisałem wyżej to pierwsze wydaje mi się lepsze. -
Monika M.:
Mimo powyższego, tj. możliwości otwierania tego samego formularza w różnych trybach - zastanowiłabym się nad utworzeniem osobnych formularzy dla różnych grup użytkowników. Np. dzięki temu można by było ukryć niektóre pola - byłyby niewidoczne itp.
Takie otwieranie w różnych trybach jest fajne, o ile chodzi o proste formularze, natomiast, jeśli pojawiają się jakieś przyciski typu "Edycja", "Usuń", "Dodaj" itp., które mają być "włączone" w zależności od różnych przypadków, to otwieranie takiego formularza komplikuje kod i ja osobiście wolę w takich przypadkach osobne formularze.
W tym projekcie należałoby się zastanowić, co dalej będzie potrzebne i rozważyć, jakie rozwiązanie będzie lepsze.
Ja jestem przeciwnikiem 2 formularzy do tego samego, kiedyś też stosowałem takie rozwiązanie, ale drażniło mnie że w przypadku redesignu muszę to robić x2...
Co do przycisków usuń/edytuj/wklej to ja zawsze mam tabele z opisanym paskiem narzędzi, (używam standardowego microsoftowego toolbara), w której jest pole kiedy ma być włączone, i teraz przy otwarciu formularza jest jedna funkcja odpowiedzialna za wygląd toolbarsa i zależnie od konfiguracji pokazuje lub nie, bądź też wyłącza przyciski, także skomplikowanie to jedna linijka kodu w kodzie przy otwarciu, a funkcja jest w module i wykorzystywana przez reszte formularzy -
Ciężko mi zrozumieć o co chodzi więc rozwiniemy to w punktach:
1. Jestem na formularzu A (edycja zablokowana)
2. Klikam przycisk A1
3. Otwiera się formularz B (edycja dozwolona)
4. Klikam przycisk B1
5. Robię kopię rekordu i edytuje
Naprowadź czy dobrze zrozumiałem, a może wyjdźmy bardziej ogólnie,
opisz istote problemu bez rozważań technicznych bo trudno to zrozumieć.
Z tego co mi sie wydaje to chcesz mieć historyczność zmian danego rekordu,
ale nie wiem czy dobrze wnioskuje...
Próbowałem przypiać przycisk polecenia pod zdarzenie formularza (przy
otwarciu, po załadowaniu) ale nic nie chciało chodzić. Nie wiem jak poprostu
połoczyć zdarzenie formularza z polecenim kryjącym się pod przyciskiem. Na
jakimś przykaldzie byłoby mi łatwiej.
Tego to już nie rozumiem, jeżeli chcesz wywołać zdarzenie przycisku w zdarzeniu przy otwerciu formularza to wpisz w kodzi:
Call nazwa_przycisku_Cilck()
Michał Dziubek edytował(a) ten post dnia 20.09.11 o godzinie 16:45 -
Przemysław R.:
W odróżnieniu od Ciebie myślę szerzej niż tylko rozwiązanie doraźne problemu, proponuję rozwiązanie systemowe zgodne z zasadami sztuki a nie gaszenia pożaru
Co do normalizacji danych łatwo wtedy zmienić narzędzie do pivotowania np. może być to widok tabeli w układzie tabeli przestawnej w samym accessie, tudzież inne wynalazki typu OLAP ale już poza acceseem np. PoverPivot.
I własnie o to mi chodzi, nie przyczepiłbym się do Twojej odpowiedzi, gdybyś
to napisał w pierwszym poście, wtedy by to miało jakiś sens. A tak autor może to interpretować różnie, a napewno nie wniosło to wiele do dyskusji.
widzę że kolega kiepsko zna Access-a
Przyjmuje na klatę ;)
Workaround:
Wygenerować 2 (lub więcej tabel) tymczasowych, wpisać do każdej numer rekordu kopiować dane, jak wyczerpiesz limit pierwszej dajesz do drugiej itd. zachowując numer rekordu.
Pokazujesz raport dla tabeli 1 i tabeli 2 sortując po numerze rekordu.
druciarstwu mówimy zdecydowane nie!
A czemu, wiele by się chłopak nauczył pisząc takie rozwiązanie... i jak zaznaczyłem jest to obejście problemu nie jego rozwiązanie.