You do not give an example of the initial input and the desired output. However, if i understood correctly, assuming today is July 2020 and you have:
** TODO My task 1
SCHEDULED: <2020-06-28 Fri>
My task 1 description
** DONE My task 2
SCHEDULED: <2020-06-29 Sat>
My task 2 description
** DONE My task 3
My task 3 description
** DONE My task 4
My task 4 description
this should do what you want:
(defun my-arch ()
(defun my-arch-map ()
(unless (string= (org-element-property :raw-value (org-element-at-point)) "Tasks")
(setq org-map-continue-from (org-element-property :begin (org-element-at-point)))))
Specifically, if you put your cursor at Tasks level and execute
M-x my-arch, the Task 2 and 3 (done in the past month) are archived.
Task 1, occurred in the past, but undone is not archived.
Task 4, done in the current month, is not archived.
As regards the code,
org-map-entries applies a function (here
my-arch-map) to everything matching a condition.
The condition here is set dynamically on the basis of the current date, assumed something in July 2020.
to learn about setting conditions.
The scope of
org-map-entries is the tree, so nothing is done outside the tasks subtree.
After parsing an entry,
org-map-entries skips to the next one. However, if your action implies removing the entry (such as here when archiving), the cursor is automatically placed on the next, so the skip would just cause an incorrect parsing here. To avoid this, with
org-map-continue-from, you bring the cursor back to the beginning of current element, so the skip does not harm.
unless condition is not strictly necessary here, but could turn handy for alternate matching. In fact, since the scope of
org-map-entries is the tree, the whole Tasks subtree is parsed first and then the subtree elements. If you use a negative condition, such as archiving everything not marked as TODO, then the entire Tasks subtree matches and is archived disregarding its element values.
Also is you condition is only related to the
SCHEDULING property, no property at Tasks level means a matching and so again it would be archived.
To avoid this edge cases, we set to never parse an entry, such as the main one, whose raw value is "Tasks".