If having a field (automatic update) is not a requirement, then this works.
I modified it to fit your title block name & attribute.
It'll automatically fill out sheet #. But if you move the layout tabs around, you'll have to re-run tabnumber command.
(defun c:tabnumber (/ _put a blk_name e i n s tag_name)
(defun _put (blk tag val)
(vl-some
'(lambda (x) (and (wcmatch (vla-get-tagstring x) (strcase tag)) (vla-put-textstring x val)))
(vlax-invoke blk 'getattributes)
)
)
;; Edit below for your use
(setq blk_name "BORDER" ; "YOURTITLEBLOCKNAME"
tag_name "SHT" ; "YOURATTRIBUTETAG"
)
(setq i (itoa (length (layoutlist))))
(vlax-for l (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
(setq a (cons (list (vla-get-name l) (vla-get-taborder l)) a))
)
(if (setq s (ssget "_A" (list '(0 . "INSERT") (cons 2 blk_name) '(66 . 1))))
(foreach b (mapcar 'cadr (ssnamex s))
(if (setq n (cadr (assoc (cdr (assoc 410 (entget b))) a)))
; (_put (vlax-ename->vla-object b) tag_name (strcat "Page " (itoa n) " of " i))
(_put (vlax-ename->vla-object b) tag_name (itoa n))
)
)
)
(princ)
)