Yup, there's Tons of different ways.

But first, why doesn't Joe's program work...
  1. There's no way out of the Start: loop. It never makes it to combo:
  2. There are too many nested gosubs. It'll overflow the stack before it gets a full combination entered. You only get 4 levels.
  3. Spaghetti code like that needs Marinara, not Picante sauce.
So here's one of those other ways. It has 2 security levels, timeouts, and an easy to set Code in EEPROM.
Code:
@MyConfig = _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF 
@MyConfig = MyConfig & _BODEN_OFF 
@ __config  MyConfig
'@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON  & _LVP_OFF & _CP_OFF

CLEAR

;________________________User Configurable Settings___________________________
DEFINE HIGH_SECURITY  1  ; For HIGH_SECURITY, the user is required to enter
                         ; the exact number of digits, Followed by the # sign
MaxTime  CON 5000        ; Timeout if no keypress, in ms
Data @0, 5, "78A5D"      ; Length of, and The Combination
                         ; Since it's in EEPROM, it can be changed later.
;_____________________________________________________________________________    
                    
 
Define PIC16F877A
@ errorlevel -230
CMCON  = 7  
ADCON1 = 7 
define OSC 20
TrisD = %00000000

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4

disable debug
    include "keypad.bas"
enable debug
    
DEFINE KEYPAD_ROW        4        ' 4 ROW keypad       
DEFINE KEYPAD_ROW_PORT   PORTB    ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT    4        ' ROW0 = PORTB.4
DEFINE KEYPAD_COL        4        ' 3 COL keypad
DEFINE KEYPAD_COL_PORT   PORTB    ' COL port = PORTB
DEFINE KEYPAD_COL_BIT    0        ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50       ' debounce delay = 50 mSec
DEFINE SCAN_ONCE         1

ByteA       var byte
ComboLength VAR BYTE
ComboPtr    VAR BYTE
Timeout     VAR WORD
Failed      VAR BIT
ReStart     VAR BIT

OPTION_REG.7=0        ' Enable the Excellent internal PORTB pull-ups :D
TRISB = %11110000     ' Set Keypad I/O 
PORTB = 0             ' Set columns LOW 
INTCON = %10001000    ' Enable global interrupt, and PORTB change
  
on interrupt goto KeypadInt   ; ON INTERRUPT ???? :)

Init:
    ReStart = 0
    lcdout $FE,1
    pause 500
    Failed = 0
    Read 0, ComboLength
    lcdout $FE,1,"Press any Key"
Start:
    pause 1
    Timeout = Timeout - 1
    if (ComboPtr > 0) and (Timeout = 0) then Gosub Reset
    if ReStart then Init
goto Start

;_____________________________________________________________________________    
disable
@  ifndef HIGH_SECURITY
@     #define HIGH_SECURITY 0                    ; default to Low security
@  endif

KeypadINT:    
    @ READKEYPAD _ByteA                          ; Get the keypress
    TRISB=%11110000                              ; Reset I/O's
    PORTB=0                                      ; Set all columns LOW
    INTCON.0=0                                   ; Clear RBIF
    Timeout = MaxTime                            ; Reset the Timeout
    lookup ByteA,[0,"123A456B789C*0#D"],Key      ; convert keypress
    ComboPtr = ComboPtr + 1                      ; point to next digit
@   if HIGH_SECURITY == 1
        LCDOUT $FE, $C4 + ComboPtr, "*"          ; print a Mask character
        if Key = "*" then Reset
        if Key = "#" then Finish
@   endif
    if ComboPtr <= ComboLength then
        Read ComboPtr, ByteA                     ; Get the digit from EEPROM
        if Key = ByteA then                      ; is it the same ?
            Read 0, ByteA                        ; Get the length of the combo
@       if  HIGH_SECURITY == 0
            LCDOUT $FE, $C4 + ComboPtr, "*"      ; print a Mask character
            if ComboPtr = ByteA then AccessGranted   ; Done?, Grant Access
@       endif
        else
@       if HIGH_SECURITY == 0
            ComboPtr = 0                         ; Wrong digit
            goto  AccessDenied                   ; terminate entry
@       else                                     ; -HIGH_SECURITY-
            Failed = 1                           ; let them keep entering
@       endif                                    ; makes it harder to figure
        Endif                                    ; the combination
    endif
resume                                           ; must end with # sign

AccessGranted:
    ComboPtr = 0
    lcdout $FE,1,"  Gate Opening"
    PortD.2 = 1
    pause 30000
    lcdout $FE,1,$FE,$C0,"  Gate Closing"
    pause 30000
    ReStart = 1
resume

AccessDenied:
    ComboPtr = 0
    LCDOUT $FE, 1, " Access Denied"
    ; Zapp them with 5000v to the kaypad  :)
    pause 2000
    ReStart = 1
resume

Reset:
    ComboPtr = 0
    LCDOUT $FE, 1, "  Entry Reset"
    pause 2000
    ReStart = 1
resume

Finish:
    if (Failed = 0) and (ComboPtr = ComboLength + 1) then
        goto AccessGranted
    else
        goto AccessDenied
    endif
enable