Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SQL - zliczanie znaków w słowie i polskie litery

999 views
Skip to first unread message

K Neo

unread,
Mar 6, 2005, 11:01:13 AM3/6/05
to
Tworzę bazę w MS SQL 2000 SP3.
Tabela wygląda w uproszczeniu tak:

1) ID int
2) Imie nvarchar
3) Liczbaliter int [tu ma być liczba liter np: 'ą' występujących w
odpowiedniej kolumnie Imie]


Wiem, że jest funkcja charindex(exp1,exp2,start_location), która zwraca
indeks do pierwszego
wystąpienia exp1 w exp2. Przy tworzeniu Formula dla Column Liczbaliter
użyłem testowo formuły:
(charindex,('ą',[Imie],0)).

1) Jak należy rozszerzyć tę formułę, aby w kolumnie Liczbaliter pojawiła się
łączna liczba
wystąpień litery 'ą' a nie indeks jej pierwszego wystąpienia. Wiem, że
należałoby zbudować
jakąś procedurę, która by to obsługiwała, ale pytanie jest takie:

a) czy można to zrobić w polu Formula dla danej kolumny i jak to zrobić,
b) jeśli nie to gdzie należy umieścić takąż procedurę.

Chciałbym, żeby ta wartość w kolumnie Liczbaliter była automatycznie
aktualizowana przy
każdej modyfikacji poila Imie.

2) Mam problem z polskimi znakami: mianowicie, gdy w Formula wpisuję
(charindex,('ą',[Imie],0))
i zapiszę to, to gdy powtórnie wchodzę do edycji to litera traci ogonek i
zamienia się na a.
Chciałbym, żeby w formule można było wyszukiwać polskie znaki.

Z góry dziękuję za wszelką pomoc


Błażej Strus

unread,
Mar 6, 2005, 3:02:53 PM3/6/05
to
K Neo napisał(a):

> 1) Jak należy rozszerzyć tę formułę, aby w kolumnie Liczbaliter pojawiła się
> łączna liczba wystąpień litery 'ą' a nie indeks jej pierwszego wystąpienia.
> Wiem, że należałoby zbudować jakąś procedurę (...)

Nie wiem na ile to Ci się przyda, bo nie "budowałem" procedur
w MS Sql'u. Ale jeśli zadajesz to pytanie na tej grupie, rozumuję,
że wykorzystujesz Accessa. Zatem i VBA... A jeśli tak, to liczbę
wystąpień danego znaku możesz otrzymać w ten sposób:

Public Function CountChar(ByVal strIn As String, _
ByVal strChar As String, _
Optional lngCompare As VbCompareMethod = vbBinaryCompare) As Long
' strIn - ciąg, w którym zliczamy liczbę wystąpień danego znaku
' strChar - znak, którego liczbę wystąpień zliczamy
' lngCompare - metoda porównań

Dim astrItems() As String
astrItems = Split(strIn, strChar, , lngCompare)
CountChar = UBound(astrItems) - LBound(astrItems)

End Function

Można jeszcze dodać: if len(strChar) <> 0, ale bez przesady...

Blazek

(c) Krzysztof Pozorek

unread,
Mar 6, 2005, 5:28:58 PM3/6/05
to
(...)

> Dim astrItems() As String
> astrItems = Split(strIn, strChar, , lngCompare)
> CountChar = UBound(astrItems) - LBound(astrItems)

Fajne jest tez:
=Len(str)-Len(Replace(str,"ą",""))

K.


Krzysztof Naworyta

unread,
Mar 7, 2005, 8:39:16 AM3/7/05
to
(c) Krzysztof Pozorek <acc...@vis.pl> napisał:

| (...)
|| Dim astrItems() As String
|| astrItems = Split(strIn, strChar, , lngCompare)
|| CountChar = UBound(astrItems) - LBound(astrItems)


ep? chyba:
CountChar = UBound(astrItems) - LBound(astrItems) + 1

a tak naprawdę
CountChar = UBound(astrItems) + 1

bo Split jest "zero-based"

czyli krócej:

? Ubound(Split(strIn, strWhat,,lngCompare))+1

| Fajne jest tez:
| =Len(str)-Len(Replace(str,"ą",""))

w ogólności:

= (Len(str)-Len(Replace(str,"ąc","")))/Len("ąc")

;-)

--
KN


BraZby

unread,
Mar 7, 2005, 2:54:52 PM3/7/05
to

Użytkownik "(c) Krzysztof Pozorek" <acc...@vis.pl> napisał w wiadomości
news:d0g089$cma$1...@atlantis.news.tpi.pl...

[...]

Małe (krótkie) jest pieknę, ale:
Nie przedstawiam wyników, (każdy może sprawdzić), ale Split i Replace
jest moim zdaniem zdecydowanie wolniejsze od klasycznego InStr
ok. *25x* dla długiego ciagu znaków i ok. 5x dla krótkiego ciągu
i na dodatek InStr działa w Acc'97:

'__________________________________________________
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
'______________________________
Private Sub Polecenie0_Click()
Dim sStr1 As String
Dim i As Integer
Const MY_TO As Long = 15
Const MY_REPEAT As Long = 100000
Const MY_CHAR As String = "ą"
Const MY_STRING As String = "ćśdę łókjąldimna ąddgfdn"

DoCmd.Hourglass True
zbShortString MY_STRING, MY_CHAR, MY_REPEAT
Debug.Print String(120, "=")
sStr1 = MY_CHAR & MY_STRING & MY_CHAR
For i = 0 To MY_TO
sStr1 = sStr1 & sStr1
Next
zbLongString sStr1, MY_CHAR
DoCmd.Hourglass False
End Sub
'___________________________________________
Private Sub zbShortString(sStr As String, _
sChars As String, _
lRepeat As Long)
Dim lStart As Long
Dim lCount As Long
Dim lInStr As Long
Dim lLenChars As Long
Dim astrItems() As String
Dim i As Long
Dim sTmp As Long
'========================================
lStart = timeGetTime
For i = 0 To lRepeat
lLenChars = Len(sChars)
lInStr = InStr(1, sStr, sChars, vbBinaryCompare)
Do Until lInStr = 0
lInStr = InStr(lInStr + lLenChars, sStr, _
sChars, vbBinaryCompare)
lCount = lCount + 1
'trochę wydłuża czas, ale tytułem sprawdzenia
If i = 0 Then sTmp = lCount
Loop
Next
Debug.Print "1. Short: Czas: ", timeGetTime - lStart, _
"Wywołań: ", lRepeat, "Znaków: ", Len(sStr), _
"Wystąpień: ", sTmp
'========================================
lStart = timeGetTime
For i = 0 To lRepeat
lCount = Len(sStr) - Len(Replace(sStr, sChars, "", 1, , _
vbBinaryCompare))
Next
Debug.Print "2. Short: Czas: ", timeGetTime - lStart, _
"Wywołań: ", lRepeat, "Znaków: ", Len(sStr), _
"Wystąpień: ", lCount
'========================================
lStart = timeGetTime
For i = 0 To lRepeat
astrItems = Split(sStr, sChars, , vbBinaryCompare)
lCount = UBound(astrItems) - LBound(astrItems)
Next

Debug.Print "3. Short: Czas: ", timeGetTime - lStart, _
"Wywołań: ", lRepeat, "Znaków: ", Len(sStr), _
"Wystąpień: ", lCount
End Sub
'____________________________________________
Private Sub zbLongString(sStr As String, sChars As String)
Dim lStart As Long
Dim lCount As Long
Dim lInStr As Long
Dim lLenChars As Long
Dim astrItems() As String
'========================================
lLenChars = Len(sChars)
lStart = timeGetTime
lInStr = InStr(1, sStr, sChars, vbBinaryCompare)
Do Until lInStr = 0
lInStr = InStr(lInStr + lLenChars, sStr, sChars, _
vbBinaryCompare)
lCount = lCount + 1
Loop
Debug.Print "4. Long: Czas: ", timeGetTime - lStart, _
"Wywołań: ", 1, "Znaków: ", Len(sStr), _
"Wystąpień: ", lCount
'========================================
lStart = timeGetTime
lCount = Len(sStr) - Len(Replace(sStr, sChars, "", 1, , _
vbBinaryCompare))
Debug.Print "5. Long: Czas: ", timeGetTime - lStart, _
"Wywołań: ", 1, "Znaków: ", Len(sStr), _
"Wystąpień: ", lCount
'========================================
lStart = timeGetTime
astrItems = Split(sStr, sChars, , vbBinaryCompare)
lCount = UBound(astrItems) - LBound(astrItems)
Debug.Print "6. Long: Czas: ", timeGetTime - lStart, _
"Wywołań: ", 1, "Znaków: ", Len(sStr), _
"Wystąpień: ", lCount
End Sub

--
Pozdrowienia
BraZby
www.bratki.w.v1.pl dział Access

Błażej Strus

unread,
Mar 8, 2005, 7:39:33 AM3/8/05
to
> ep? chyba:
> CountChar = UBound(astrItems) - LBound(astrItems) + 1
>
Chyba nie...
?CountChar("aaa","a") przy
CountChar = UBound(astrItems) - LBound(astrItems
daje 3,
a przy:

CountChar = UBound(astrItems) - LBound(astrItems) + 1
daje 4.

> a tak naprawdę
> CountChar = UBound(astrItems) + 1
>
> bo Split jest "zero-based"
>
> czyli krócej:
>
> ? Ubound(Split(strIn, strWhat,,lngCompare))+1
>
No i znowu... to będzie tak przy założeniu, że
wstawimy "Option Base 0", lub nie wstawimy "Option Base"
w ogóle. Bo jeśli wstawimy "Option Base 1", to - patrz wyżej.

Ale! Komu ja tu odpisuję! Już się chowam pod stół ;)

Blazek

Marcin Miga

unread,
Mar 8, 2005, 8:38:19 AM3/8/05
to
Błażej Strus wrote:

> > a tak naprawdę
> > CountChar = UBound(astrItems) + 1
> >
> > bo Split jest "zero-based"
> >
> > czyli krócej:
> >
> > ? Ubound(Split(strIn, strWhat,,lngCompare))+1
> >
> No i znowu... to będzie tak przy założeniu, że
> wstawimy "Option Base 0", lub nie wstawimy "Option Base"
> w ogóle. Bo jeśli wstawimy "Option Base 1", to - patrz wyżej.
>
> Ale! Komu ja tu odpisuję! Już się chowam pod stół ;)
>

Tak. I nie wychodź spod niego... :)
Split ma gdzieś to co wpiszesz w Option Base.

--
Marcin M. Miga
Poznańscy to my:
http://tiny.pl/hxmq, http://tiny.pl/hxxv, http://tiny.pl/hxxb

Błażej Strus

unread,
Mar 8, 2005, 1:06:38 PM3/8/05
to
>>>bo Split jest "zero-based"

> Split ma gdzieś to co wpiszesz w Option Base.
Słuszna uwaga. Split zawsze zaczyna od 0.
Zatem po uproszczeniu będzie:
Ubound(Split(strIn, strWhat,,lngCompare))
oczywiście po wcześniejszym sprawdzeniu czy len(strIn)>0

Blazek

0 new messages