Selasa, 26 Mei 2015

Pembahasan Fingerprint dari Programmer VB Indonesia

[ASK | VB.NET] Menyimpan data yang sebelumnya belum didownload darifingerprint ke database
Saya sedang membuat aplikasi absensi fingerprint dengan Zkemkeeper.
Saya ada masalah kaya gini :

Pertama saya klik tombol download log datanya, dan semuanya berhasil masuk ke database, lalu pada hari selanjutnya ada penambahan log data, ketika saya download lagi gimana caranya agar hanya penambahan log data tersebut yang masuk ke database, tidak semuanya. Apakah di zkemkeeper ada method seperti itu? atau saya harus bermain di bagian database saja?
Mohon pencerahannya om.
Note : Saya sudah baca buku manualnya dan sejauh ini saya tidak menemukannya. (Takutnya saya yang teledor baca jadi nanya disini).

seingat saya memang nggak ada. setiap kali mengambil log finger print dari mesin, seluruh log akan diload ke memori.

Untuk itu perlu bikin kebijakan sendiri supaya data nggak dua kali dimasukkan ke database.
ada beberapa cara yang bisa dipakai:

1. setelah semua data disimpan ke database, kosongkan /hapus log data mesin. dengan demikian pada pengambilan berikutnya hanya data baru saja yang diambil.

2. bikin filter sendiri. simpan waktu terakhir yang ada di mesin pada pengambilan data terakhir. pada waktu pengambilan data berikutnya, pastikan hanya data yang sesudah waktu terakhir saja yang disimpan. misalnya pada hari ini ada pengambilan data. log terakhir tercatat adalah 2014-10-05 17:15:31. Esok hari, pastikan data yang akan disimpan adalah 
data sesudah 2014-10-05 17:15:31.

kalo mesin bisa komunikasi melalui TCP/IP mending bikin realtime notification aja.

realtime notification ketika terjadi log event.
misal, ketika karyawan melakukan absen.
ketika menempelkan tangan di sensor, data kehadiran otomatis disimpan dikomputer bukan disimpan dimesin.




mengambil fingerprint => mengambil data fingerprint yang diregister di mesin.
http://www.codeproject.com/Questions/639411/Attendance-Machine-and-Asp-Net

Public axCZKEM1 As New zkemkeeper.CZKEM
 

 
Private bIsConnected = False
Private iMachineNumber As Integer
 
'Vb Code  Convert to c#
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
 
Dim idwErrorCode As Integer
Cursor = Cursors.WaitCursor
If btnConnect.Text = "Disconnect" Then
axCZKEM1.Disconnect()
bIsConnected = False
btnConnect.Text = "Connect"
MsgBox("Disconnected")
Cursor = Cursors.Default
Return
End If
 
bIsConnected = axCZKEM1.Connect_Net(txtIP.Text.Trim(), Convert.ToInt32(txtPort.Text.Trim()))
If bIsConnected = True Then
btnConnect.Text = "Disconnect"
btnConnect.Refresh()
MsgBox("Connected")
iMachineNumber = 1
axCZKEM1.RegEvent(iMachineNumber, 65535)
Else
axCZKEM1.GetLastError(idwErrorCode)
MsgBox("Unable to connect the device,ErrorCode=" & idwErrorCode, MsgBoxStyle.Exclamation, "Error")
End If
Cursor = Cursors.Default
 
End Sub
#End Region
 

''Vb Code  Convert to c#
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim dwEnrollNumber As Long
Dim name As String
Dim password As String
Dim privileg As Long
Dim conexaoMySQL As SqlConnection
Dim strSQL As String
Dim dwVerifyMode As Long
Dim dwInOutMode As Long
Dim timeStr As String
Dim enable As Boolean
Dim _data As New System.Text.StringBuilder
Dim _errorCode As Integer
Dim _machineNumber As Integer
Dim _enrollNumber As Integer
Dim _enrollMachineNumber As Integer
Dim _verifyMode As Integer
Dim _inOutMode As Integer
Dim _year As Integer
Dim _month As Integer
Dim _day As Integer
Dim _hour As Integer
Dim _minute As Integer
 
axCZKEM1.ReadMark = True
axCZKEM1.GetLastError(_errorCode)
axCZKEM1.ReadAllUserID(1)
axCZKEM1.ReadMark = True
If (axCZKEM1.ReadGeneralLogData(1)) Then
axCZKEM1.GetLastError(_errorCode)
While axCZKEM1.GetGeneralLogData(1, _machineNumber, _enrollNumber, _enrollMachineNumber, _verifyMode, _inOutMode, _year, _month, _day, _hour, _minute)
axCZKEM1.GetGeneralLogDataStr(1, dwEnrollNumber, dwVerifyMode, dwInOutMode, timeStr)
axCZKEM1.GetUserInfo(1, dwEnrollNumber, name, password, privileg, enable)
Dim data1 As Integer = 0
Dim data2 As Integer = 1000000
conexaoMySQL = New SqlConnection("Data Source=Ahmad-PC;Initial Catalog=HR;User ID=sa;Password=*******")
If data1.ToString < _minute Then
strSQL = "INSERT INTO InOut (dwEnrollNumber,name,password,privileg,dwVerifyMode,dwInOutMode,timeStr,_machineNumber,_enrollNumber,_enrollMachineNumber,_verifyMode,_inOutMode,_year,_month,_day,_hour,_minute) VALUES ( '" & dwEnrollNumber & "','" & name & "','" & password & "','" & privileg & "','" & dwVerifyMode & "','" & dwInOutMode & "','" & timeStr & "','" & _machineNumber & "','" & _enrollNumber & "','" & _enrollMachineNumber & "','" & _verifyMode & "','" & _inOutMode & "','" & _year & "','" & _month & "', '" & _day & "','" & _hour & "','" & _minute & "')"
 
End If
Dim cmd As New SqlCommand(strSQL, conexaoMySQL)
conexaoMySQL.Open()
cmd.ExecuteNonQuery()
conexaoMySQL.Close()
End While
End If
axCZKEM1.RefreshData(1)
Dim query As String = "SELECT * FROM InOut"
Dim connection As New SqlConnection("Data Source=Ahmad-PC;Initial Catalog=HR;User ID=sa;Password=*******")
Dim da As New SqlDataAdapter(query, connection)
Dim ds As New DataSet()
If da.Fill(ds) Then
DataGridView5.DataSource = ds.Tables(0)
End If
DataGridView5.FirstDisplayedScrollingRowIndex = DataGridView5.Rows.Count - 1
 
End Sub

Gan saya sudah melakukan script yang agan kasih waktu itu yang ada di code project ketika saya cek inputan di database malah masuk data ini bukan data kehadiran karyawannya.
Data itu buat apa ya?



itu data kehadiran, dan disitu juga ada juga informasi dari specified user (axCZKEM1.GetUserInfo).

pada fungsi ini : axCZKEM1.GetGeneralLogData(1, _machineNumber, _enrollNumber, _enrollMachineNumber, _verifyMode, _inOutMode, _year, _month, _day, _hour
 _minute)

itu data kehadiran gan?
tapi ketika saya jalankan perintah nya dua kali gak bisa, harusnya kan semua data karyawan yang absen muncul semua..


untuk yang verifyMode dan inOutMode nilai nya 0 disini mas

mmm gmana ya..
coba pada axCZKEM1.GetUserInfo(1, dwEnrollNumber, name, password, privileg, enable)
pada argument dwEnrollNumber ganti dengan user id yang sering absen.

lalu jalankan lagi.

inOutMode 0 = Check in, 1 = Check out.
kalo verify mode 0 berarti terdapat beberapa kemungkin. bisa dengan sidik jari, bisa dengan password atau dengan RF.

Dim dwEnrollNumber As Long . itu berarti dwEnrollNumber nilainya 0 kan?

[ASK][Codingan dari Penanya]
Private Sub BtnGetData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim dwEnrollNumber As Long
Dim name As String
Dim password As String
Dim privileg As Long
Dim strSQL As String
Dim dwVerifyMode As Long
Dim dwInOutMode As Long
Dim timeStr As String
Dim enable As Boolean
Dim _data As New System.Text.StringBuilder
Dim _errorCode As Integer
Dim _machineNumber As Integer
Dim _enrollNumber As Integer
Dim _enrollMachineNumber As Integer
Dim _verifyMode As Integer
Dim _inOutMode As Integer
Dim _year As Integer
Dim _month As Integer
Dim _day As Integer
Dim _hour As Integer
Dim _minute As Integer

zkem.ReadMark = True
zkem.GetLastError(_errorCode)
zkem.ReadAllUserID(1)
zkem.ReadMark = True
If (zkem.ReadGeneralLogData(1)) Then
zkem.GetLastError(_errorCode)
zkem.GetGeneralLogData(1, _machineNumber, _enrollNumber, _enrollMachineNumber, _verifyMode, _inOutMode, _year, _month, _day, _hour, _minute)
zkem.GetGeneralLogDataStr(1, dwEnrollNumber, dwVerifyMode, dwInOutMode, timeStr)
zkem.GetUserInfo(1, dwEnrollNumber, name, password, privileg, enable)
Dim data1 As Integer = 0
Dim data2 As Integer = 1000000

konek()
strSQL = "INSERT INTO tb_data (dwEnrollNumber,name,password,privileg,dwVerifyMode,dwInOutMode,timeStr,_machineNumber,_enrollNumber,_enrollMachineNumber,_verifyMode,_inOutMode,_year,_month,_day,_hour,_minute) VALUES ( '" & dwEnrollNumber & "','" & name & "','" & password & "','" & privileg & "','" & dwVerifyMode & "','" & dwInOutMode & "','" & timeStr & "','" & _machineNumber & "','" & _enrollNumber & "','" & _enrollMachineNumber & "','" & _verifyMode & "','" & _inOutMode & "','" & _year & "','" & _month & "', '" & _day & "','" & _hour & "','" & _minute & "')"
Dim cmd As MySqlCommand

Try
cmd = New MySqlCommand(strSQL, conn)
cmd.ExecuteNonQuery()
Catch ex As Exception
MsgBox("GAGAL", MsgBoxStyle.Critical, "Kesalahan")
End Try
End If
End Sub

dwVerifyMode adalah data long. anda menyimpannya ke database sebagai varchar.
coba lihat juga alternatif lain dari fungsi-fungsi itu. Di SDK yang saya punya , selain fungsi/method GetGeneralLogData() ada alternatif method yang tujuannya sama: SSR_GetGeneralLogData(). Ini mungkin method baru yang dibuat sebagai pengganti method yang lama.
itu kan belum di iterasikan mas.
while zkem.GetGeneralLogData(1, _machineNumber, _enrollNumber, _enrollMachineNumber, _verifyMode, _inOutMode, _year, _month, _day, _hour, _minute)


end while


yap GetGeneralLogData digunakan untuk mengambil attendance records.
Yang perlu diperhatikan layar mesinnya apakah BW atau TFT. Yang saya tau kalo beda layar beda algoritmanya.
coba di tampilkan ke tabel dahulu saja.
coba source ini.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim UserID As Integer
Dim Verify As Integer
Dim InOut As Integer

Dim iYear As Integer
Dim iMonth As Integer
Dim iDay As Integer
Dim iHour As Integer
Dim iMinute As Integer

Dim eMachineNumber As Integer
Dim tMachineNumber As Integer

Dim lvItem As New ListViewItem("Items", 0)

Dim i As Integer = 0

With ListView2
.View = View.Details
.GridLines = True
.Columns.Add("No.", 100)
.Columns.Add("User ID", 100)
.Columns.Add("Verify", 100)
.Columns.Add("InOut Mode", 100)
.Columns.Add("Date and Time", 100)
End With

Dim strDateTime As String = String.Empty

ListView2.Items.Clear()
If axCZKEM1.ReadGeneralLogData(1) Then
While axCZKEM1.GetGeneralLogData(1, tMachineNumber, UserID, eMachineNumber, Verify, InOut, iYear, iMonth, iDay, iHour, iMinute)
i += 1

strDateTime = iYear & "-" & iMonth & "-" & iDay & " " & iHour & ":" & iMinute

lvItem = ListView2.Items.Add(i.ToString())
lvItem.SubItems.Add(UserID)
lvItem.SubItems.Add(Verify)
lvItem.SubItems.Add(InOut)
lvItem.SubItems.Add(strDateTime)

Application.DoEvents()
End While
End If
End Sub

Cara ngeliat bedanya BW atau TFT gimana gan?
BW(Hitam putih) TFT (Warna) disesuaikan dengan display layar anda.


gan saya udah coba source code yang agan kasih..
Tapi UserID nya kok gitu ya?
itu user ID apa?


"kalo mau ngambil user id yang 1,2,3,4 sama 11 gimana ya?"
Harus dipahami dulu pdf yang diberikan oleh mastah VB itu. Disitu setidaknya ada tiga konsep terpisah:
a. mengambil data user

b. mengambil data template sidik jari
c. mengambil log sidik jari (yaitu data scan pada saat orang melakukan presensi).

masing-masing konsep bisa memiliki lebih dari satu method. nah pelajari dulu itu.

sepengetahuan saya, data yang diambil dari mesin tidak bisa diquery dengan filter tertentu. misalnya, kita tidak bisa mengambil data user A atau B saja. Setiap kali menjalankan perintah pengambilan data, semua data akan diambil dan ditaruh di dalam memori (komputer/pc). 
bila anda ingin memfilternya ,lakukan itu pada saat iterasi.

while zkem.GetGeneralLogData (..................)
if userid = 0 then 
continue while '<skip pembacaan
end if

i+=1
lsitem.add (...........)
end while

ok deh saya pelajari lagi, tapi pasti memerlukan waktu yang agak lama..
Nah sambil saya belajar saya mau tanya dulu sebelum nya, kan mas ezra bilang ada 3 tahapan yaitu mengambil data user, data template sidik jari, mengambil log sidik jari..


Dan source code yang mas Nur kasih itu mengambil log sidik jari kan?
Nah kalo ingin di relasikan dengan data user, field mana yang di hubungkan?

"Nah kalo ingin di relasikan dengan data user, field mana yang di hubungkan"
field dwenrollnumber

oh gitu, oiya mas ezra berkenan gak kalo mas menjelaskan masing masing variabel ini 

1, _machineNumber, _enrollNumber, _enrollMachineNumber, _verifyMode, _inOutMode, _year, _month, _day, _hour, _minute


soalnya saya bingung bagian itu juga

 itu di method apa?
kalau method yang anda pakai tidak ada di manual itu, berarti method itu sudah obsolete. pakai method yang namanya mirip yang ada di manual itu.
contoh, bila di manual tidak ada method GetGeneralLogData, coba pakai SSR_GetGeneralLogData(), kurang lebih fungsinya sama, dengan penambahan parameter out saja.
contoh, bila di manual tidak ada method GetGeneralLogData, coba pakai SSR_GetGeneralLogData(), kurang lebih fungsinya sama, dengan penambahan parameter out saja.

 "kata 'method' disini apa maksudnya mas saya belum ngerti"
method adalah function /procedure dari suatu class.

class foo()
function dosomething() as integer << this is method
end function 

property something as string << this is property
end class

gan saya udah coba 2 method.. kalo yang pake SSR_GetGeneralLogData itu hasil date nya kaya gini

Kalo pake GetGeneralLogData date nya malah jadi gini


ko aneh ya. colonthree emotikon bahkan verify dan IO mode tidak sesuai. 

coba mothod lain dari ReadGeneralLogData. Selain method tersebut anda juga bisa menggunakan ReadAllGLogData dengan Parameter yang sama.
Kemudian untuk mengambil attendance records, selain GetGeneralLogData dan SSR_GetGeneralLogData, ada metode lain yang bisa dipakai, yaitu GetAllGLogData, GetGeneralLogDataStr, dan GetGeneralExtLogData. 
Masing2 method memilik parameter yang berbeda, silahkan disesuaikan.

sebagai contoh , terlihat di situ
while zkem.ssr_GetGeneralLogData (1, theMachineNumber, userId, .....


Padahal argumen pertama adalah MachineNumber, dan argumen kedua adalah UserId. 

kayaknya TS nggak hati-hati nih dalam mengkoding.

[ASK][Coding dari Penanya]
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim UserID As String
Dim Passwd As String

Dim Privilege2 As Integer

Dim dwEnrollNumber As String

Dim lvItem As New ListViewItem("Items", 0)

Dim ii As Integer = 0

With ListView3
.View = View.Details
.GridLines = True
.Columns.Add("No.", 100)
.Columns.Add("Enroll", 100)
.Columns.Add("User Name", 100)
.Columns.Add("Password", 100)
.Columns.Add("Privilege", 100)
.Columns.Add("Privilege", 100)
End With

ListView3.Items.Clear()
If zkem.ReadAllUserID(1) Then
While zkem.GetUserInfo(1, dwEnrollNumber, UserID, Passwd, Privilege2, Enabled)
ii += 1

lvItem = ListView3.Items.Add(ii.ToString())
lvItem.SubItems.Add(dwEnrollNumber)
lvItem.SubItems.Add(UserID)
lvItem.SubItems.Add(Passwd)
lvItem.SubItems.Add(Privilege2)

Application.DoEvents()
End While
End If
End Sub

jadi kalo script itu dieksekusi hasilnya kaya gitu.
terus aja gak berhenti berhenti..

"While zkem.GetUserInfo(1, dwEnrollNumber, UserID, ...................)"

coba ganti Getuserinfo jadi getAllUserinfo .

Wah asli tokcer gan, tapi saya rubah dikit jadi SSR_GetUserInfo soalnya kalo GetUserInfo hasilnya kaya gini

tapi kalo SSR_GetUserInfo ketika di eksekusi, program malah jadi gak bisa di apa apain, semua button juga jadi disable

Nah tipe data nya kan boolean, tinggal diganti deh nilainya jadi true, beres deh

Dim WithEvents zkem As zkemkeeper.CZKEM

oh, dibuat dalam scope form, ya? Kalau ane, deklarasinya di fungsi. dan setiap kali ingin mengambil data, koneksi ke mesin dibuka dan bila telah selesai langsung ditutup.

ini contoh kodingnya:


--------------------
Public Function GetUserFromMachine(ByVal machineIp As String, ByVal port As Integer) As List(Of AttendanceUserInfoMachineInfo)
Dim rvalue As New List(Of AttendanceUserInfoMachineInfo)
Dim MachineReader As New zkemkeeper.CZKEM
Dim blconnect As Boolean
Try
blconnect = MachineReader.Connect_Net(machineIp, port)
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
Dim dwMachineNumber As Integer = 1
Dim officeId As Integer = 0
If blconnect Then
MachineReader.EnableDevice(dwMachineNumber, False)

Dim indexfinger As Integer = 0
Dim test = 0
While True
Dim Uinfo As New AttendanceUserInfoMachineInfo
Dim blUserExist = MachineReader.SSR_GetAllUserInfo(dwMachineNumber,
Uinfo.dwEnrollNumber, 
Uinfo.Name, 
Uinfo.Password, 
Uinfo.Privilage, 
Uinfo.Enabled)
If blUserExist = False Then
Exit While
End If
Uinfo.OfficeID = 0
Uinfo.MachineIP = machineIp
rvalue.Add(Uinfo)
'Debug.Print(Uinfo.dwEnrollNumber)
End While
MachineReader.EnableDevice(dwMachineNumber, True)
MachineReader.Disconnect()
Return rvalue
End If
Return Nothing
End Function
------------------

ini class untuk mengumpulkan data:
Public Class AttendanceUserInfoMachineInfo
Property dwEnrollNumber As String

Property Name As String
Property Password As String
Property Privilage As Integer
Property Enabled As Boolean
Property dwMachineNumber As Integer
Property OfficeID As Integer
Property MachineIP As String
End Class

tapi pada dasar nya sama aja ya? cuman yang coding diatas bisa putus sendiri koneksi nya ya secara otomatis? atau gimana?

Oiya mas satulagi mas, saya masih bingung dengan field ini..

apa hasil nya udah bener atau masih salah?
itu kodingnya seperti apa? 
coba aja lakukan buka/tutup koneksi seperti yang saya lakukan. lihat juga bahwa skope object zkemkeeper.CZKEM cuma pada fungsi itu saja. artinya setiap kali dipanggil, objectnya selalu baru . ini tentu mempengaruhi pembacaan di memori.

yang itu coding nya kaya gini :

If zkem.ReadGeneralLogData(1) Then

While zkem.SSR_GetGeneralLogData(1, dwEnrollNumber, Verify, InOut, iYear, iMonth, iDay, iHour, iMinute, iSecond, WorkCode)
i += 1

strDateTime = iYear & "-" & iMonth & "-" & iDay & " " & iHour & ":" & iMinute

lvItem = ListView2.Items.Add(i.ToString())
lvItem.SubItems.Add(dwEnrollNumber)
lvItem.SubItems.Add(UserID)
lvItem.SubItems.Add(Verify)
lvItem.SubItems.Add(InOut)
lvItem.SubItems.Add(strDateTime)

Application.DoEvents()
End While
End If

barangkali itu data yang usernya sudah dihapus. coba reset aja mesinnya. kayaknya kodingnya udah benar.

emang harus nya isi field User ID, Verify, dan InOut Mode harusnya gimana gan?

oh, setelah saya lihat sekali lagi. ternyata anda banyak khilafnya . grin emotikon

haha khilafnya dimana aja om? jadi gelisah nih grin emotikon

coba cari parameter UserId di baris ini:
While zkem.SSR_GetGeneralLogData(1, dwEnrollNumber, Verify, InOut, iYear, iMonth, iDay, iHour, iMinute, iSecond, WorkCode)
nggak ada, kan?
kenapa tiba-tiba ada userId di baris berikut:

lvItem = ListView2.Items.Add(i.ToString())

lvItem.SubItems.Add(dwEnrollNumber)
lvItem.SubItems.Add(UserID) <<< this one
lvItem.SubItems.Add(Verify)
lvItem.SubItems.Add(InOut)
lvItem.SubItems.Add(strDateTime)