Maybe on the lost_focus, after_update or exit event of the zip code you could use the DLookup Function.
Private Sub Zipcode_AfterUpdate()
txtCity.Text = DLookup("[City]","tblZip","[ZipCode] = '" & txtzipcode.text & "'"
txtState.Text = DLookup("[State]","tblZip","[ZipCode] = '" & txtzipcode.text & "'"
End Sub
I did not run this but I think this might be what you want.