Macros expand into other code, so in the literal, obvious sense, there isn't anything you can do with them that you can't do without them. The question is whether you can do it as briefly, as clearly, or as composably.
Here's another example. I work on a spreadsheet app. A spreadsheet has many operations that apply to either a row or a column (e.g. selecting a row/col or resizing it). The fact that they occur in transposed dimensions make them difficult to abstract over with functions. You probably end up with a bunch of boilerplate that says things like "if this is a column, change the first co-ordinate, otherwise change the second", or most likely would just write the code twice, once for the horizontal case and once for the vertical. In Lisp, we can write such a function for one dimension and then use macros to generate a transposed version of the same function that does exactly the same thing in the other dimension.
That's the first use of a macro I can wrap my head around, but it can also be done elegantly without macros - each function that acts on a row or column of data will have a "list of values" argument that could either be a list of column values from a row or a list or row values from a column.
Not quite. I wasn't clear enough. These operations are purely UI manipulations. They don't operate on lists of values or even need to know what they are. What they care about are things like: should I set a width property or a height property? To which you might reply: fine, just pass the dimension around and have a set-size function that knows whether to set width or height depending on the dimension, and so on. I say: yeah, you can do it that way, but it takes more code and is harder to read, because now you have to write it in a dimension-agnostic way, which is not how humans (or I at least) like to think about these things. It's easier to write or read the concrete version for one dimension and then say "the other dimension is just like this only transposed", which is exactly what the macro does for us.
Do you need macros to make such a program work? No. Can you use them to make the program shorter, clearer, and more generalizable? Yes.
Here's another example. I work on a spreadsheet app. A spreadsheet has many operations that apply to either a row or a column (e.g. selecting a row/col or resizing it). The fact that they occur in transposed dimensions make them difficult to abstract over with functions. You probably end up with a bunch of boilerplate that says things like "if this is a column, change the first co-ordinate, otherwise change the second", or most likely would just write the code twice, once for the horizontal case and once for the vertical. In Lisp, we can write such a function for one dimension and then use macros to generate a transposed version of the same function that does exactly the same thing in the other dimension.