我希望创建一些VBA代码,通过我的链接表(到SQL Server)查看,并输出任何字段的列表,这些字段是datetime,日期在1990年。
我想我会为每个循环需要两个这样的
For Each table in currentDB.TableDefs
For Each field in table.fields
If field.type = datetime and field.value < '1900-01-01 00:00:00'
debug.print table.name, field.name and field.value.
End IF
Next
Next
关于如何做到这一点的任何想法?
由于
答案 0 :(得分:1)
你已经有两个循环了!你好像做得对。它不起作用吗?
答案 1 :(得分:1)
VBA解决方案
基本上遍历每个表上的每个字段,寻找DateTime字段类型(整数值为8 - http://allenbrowne.com/ser-49.html)。 if if找到DateTime字段后,运行查询并查看它是否返回任何记录。
Dim db As Database
Dim t As TableDef
Dim f As Field
Dim rs As Recordset
Set db = CurrentDb
For Each t In db.TableDefs
For Each f In t.Fields
If f.Type = 8 Then
Set rs = db.OpenRecordset("SELECT " & f.Name & " FROM " & t.Name & " WHERE " & f.Name & " < #1/1/1990 12:00:00 PM#;")
If rs.EOF = False Then
Debug.Print t.Name, f.Name, rs.Fields(f.Name)
End If
rs.Close
End If
Next
Next
答案 2 :(得分:0)
如果您的字段类型是DateTime,那么您只需使用年份函数()
If year(field.value) > 1900 Then
'codes here
End If
在VB中你可以这样做
Dim dBirth as Date
For x as Integer = 0 to MyTable.rows.Count-1
dBirth = MyTable.Rows(x).Item("birthdate")
If dBirth > 1990 Then
'codes here
End If
Next
答案 3 :(得分:0)
您可以使用此存储过程:它将年份作为输入参数。 它返回具有输入年份值的列(及其表名)。
ALTER PROCEDURE [dbo].[sp_GetAllDateColumns] @startDateYear [INT]
AS
BEGIN
SET nocount ON;
-- ---------------
DECLARE @table_name NVARCHAR(100)
DECLARE @col_name VARCHAR(100)
DECLARE @sqlCommand NVARCHAR(1000)
DECLARE @count INT
-- ---------------
DECLARE @ResultArray TABLE
(
table_name NVARCHAR(100),
col_name VARCHAR(100)
)
-- ----------------
DECLARE table_cursor CURSOR FOR
SELECT ( SCH.name + '.' + TAB.name )AS tablename,
COL.name AS colname
FROM sys.schemas SCH,
sys.tables TAB,
sys.columns COL,
sys.types TYP
WHERE COL.system_type_id = TYP.system_type_id
AND TAB.object_id = COL.object_id
AND SCH.schema_id = TAB.schema_id
AND TYP.name IN ( 'datetime', 'date' );
OPEN table_cursor
FETCH next FROM table_cursor INTO @table_name, @col_name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sqlCommand = 'SELECT @cnt = COUNT(*) FROM '
+ @table_name + ' WHERE datepart(year,' +
+ @col_name + ' ) < '
+ CONVERT(NVARCHAR, @startDateYear)
EXECUTE Sp_executesql @sqlCommand, N'@cnt int OUTPUT', @cnt=@count output
IF @count >= 1
BEGIN
INSERT INTO @ResultArray(table_name, col_name)VALUES (@table_name,@col_name)
END
FETCH next FROM table_cursor INTO @table_name, @col_name
END
CLOSE table_cursor
DEALLOCATE table_cursor
--Return result
SELECT * FROM @ResultArray
END
要从SQL Server调用此过程,您所要做的就是执行此查询:
EXEC [dbo].[sp_GetAllDateColumns] @startDateYear = 2003
答案 4 :(得分:0)
在SQL术语中,您需要一个游标来遍历所有表/日期 - 列对,并在每列中查找最小的日期值。您可以将结果插入临时表中以根据需要进行分析。
很抱歉这不是VBA,但VBA不会做任何工作,只是中继SQL命令。
因此,如果您只能通过VBA访问数据库(出于任何原因),请发送此命令,并正常读取上一个select
语句的输出。
IF exists (select * from tempdb.sys.tables where name like '#Temp_results%') DROP TABLE #Temp_results
create table #Temp_results (
table_name varchar (50) null,
column_name varchar (50) null,
Min_Date datetime null
)
GO
declare @sql varchar (max), @tab varchar (50), @col varchar (50)
declare _cur insensitive cursor for
select top 2 c.name as table_name, a.name as column_name
from sys.columns a
join sys.types b on a.user_type_id = b.user_type_id
join sys.tables c on a.object_id = c.object_id
where b.name like 'date%' or b.name = 'timestamp%'
and c.type = 'U'
open _cur
fetch next from _cur into @tab, @col
while @@FETCH_STATUS = 0
begin
select @sql ='INSERT INTO #Temp_results select ''' + @tab + ''', ''' + @col + ''', (select min([' + @col + ']) from [' + @tab + '])'
--select @sql /* This is used to debug d-sql. Comment out next statement. Copy and execute SQL code. */
exec (@sql)
fetch next from _cur into @tab, @col
end
close _cur
deallocate _cur
GO
select table_name, column_name, Min_Date,
case
when Min_Date < '1900-01-01' then 'Very old date'
when Min_Date < '1990-01-01' then 'Just an old date'
else 'OK'
end How_Old_Date_Is
from #Temp_results
GO