This question comes up often. Every GIS seems to have an add-on to solve it, but they tend to be limited in what they can do. (E.g., many will only create square grids of points parallel to the coordinate axes.) I would like, therefore, to describe a simple general way to create regular grids of 2D points, suitable for use in any GIS.
Surprisingly, most of this is not really a GIS calculation: a grid can be computed even in Excel (although this is best done in a repeatable (that is, scripted) way). Then, use the GIS to select the grid points that lie within your study area. (To capitalize on this, stop right now and create a polygon feature within a feature dataset to represent the study area. Use projected coordinates in meters so you can match the metric specification of the grid.)
The idea is that any regular grid in two dimensions is addressed by row and column indexes. The direction from one column to its neighbor is a vector displacement, conveniently thought of as one "step" in the "easting" direction. The column index tells you how many steps to take, beginning from a common grid origin, in the easting direction. Likewise, the direction from one row to its neighbor is a displacement thought of as one "step" in the "northing" direction. The row index tells you how many steps to take, beginning at the same grid origin, in the northing direction.
(Why use this generality? Because you can create grids of any orientation. It is not often in the field that you have the luxury to lay out grids exactly along coordinate lines. For sampling, you might want to use a random grid with random orientation, for instance. This generality also allows you to use grids of rectangular cells (make the steps different lengths) and even triangular cells (orient the row displacement 60 or 120 degrees from the column displacement).)
All that remains is the arithmetic. As you can see, it's basically multiplying the displacements by the row and column indexes and adding them up. However, it's convenient to specify a grid in terms of (a) the coordinates of its origin, (b) the sizes of the steps, (c) the orientations of the two step directions, and (d) the numbers of columns and rows. Converting from this specification into the vector displacements needed involves computing a couple of sines and cosines; that's really the only complication.
One disadvantage of a spreadsheet solution is you either need to write a rather general macro or else you need to set up the worksheet to match the total number of points generated: not hard, but a bit of a pain. A huge disadvantage, if you're not using a macro, is the lack of reproducibility and the significant chance an error will occur.
In ArcGIS, it's convenient to script the solution in Python. In keeping, though, with the thesis that creating a grid is not a GIS operation, here is an R based solution. (R is freely downloadable and works right out of the box on many platforms, including Windows, Mac, and Linux.) You only need to edit the details (of the grid specification and output file name) and run it to create the grid attribute table.
# Specify the grid.
angles <- c(15, 105) # Orientations (in degrees) of easting and northing
length <- c(310, 310) # Grid spacings (meters), east-west and north-south
origin <- c(1735000, 285000) # Grid origin coordinates (meters, projected)
nrows <- 53 # Number of west-east strips
ncols <- 23 # Number of north-south strips
# Create the points on the grid.
basis <- rbind(cos(angles * pi/180), sin(angles * pi/180)) %*% diag(length)
x <- as.vector(outer(1:ncols, 1:nrows, FUN=function(x,y) x-1))
y <- as.vector(outer(1:ncols, 1:nrows, FUN=function(x,y) y-1))
grid <- t(basis %*% rbind(x, y) + origin)
# Display the grid.
plot(grid, asp=1, pch=19, col="Blue", cex=2 * (nrows * ncols)^(-1/4))
# Output the grid.
write.table(grid, file="f:/temp/grid.txt", sep="\t",
row.names=FALSE, col.names=c("Easting", "Northing"))
Remaining true to the philosophy that software should be used as appropriate to each task, and bearing in mind that R is not a GIS (even though it can be persuaded to do the final steps), it's time to use ArcGIS (or any other GIS you are comfortable with). To finish up, add the output file as a layer, convert it into a point layer via the "Display XY Data" option in the pop-up menu, save that as a shapefile (to make it selectable), and use
Selection|Select by location to select all points within your study area (which is easy, because you already have a polygon layer representing your study area, right?). You can export the selected points if you wish.
BTW, after adding the output file as a layer, you can modify the R script (use R's built-in script editor) and re-run it (use ^R in the editor) to change the grid. Refreshing ArcView's display shows the new results. (That's two mouse clicks: run script, refresh view.) This is a convenient way to play with the parameters to assure the grid totally overlaps your study area.
If you need a random grid, merely change some of the initial specifications in the R code to use one of its (many) random number generators. For example, using
angles <- c(0, 90) + runif(1, min=-90, max=90)
will produce a grid with a random orientation. (Setting the random number seed gives reproducible results.)
Incidentally, as a practical matter, things rarely happen in the field exactly as they appear in the GIS. Here, it's likely that some of the points that seem to be outside the study area turn out to be inside it. It's a good idea, then, not to limit your table to just those points selected by the GIS, but also to include a buffer of points that seem to fall just outside the study area, too, just in case they turn out to be needed :-).