1

我正在寻找创建一些 VBA 代码,它查看我的链接表(到 SQL Server)并输出日期时间和日期低于 1​​990 年的任何字段的列表。

我想我需要两个这样的循环

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

关于如何做到这一点的任何想法?

谢谢

4

5 回答 5

1

你已经有两个循环了!你似乎做得对。它不工作吗?

于 2013-06-13T10:43:03.907 回答
1

VBA解决方案

基本上循环遍历每个表上的每个字段以查找 DateTime 字段类型(整数值 8 - http://allenbrowne.com/ser-49.html)。如果找到 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
于 2013-06-13T14:06:45.887 回答
0

如果您的字段类型是 DateTime 那么您只需要使用 year function()

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
于 2013-06-13T10:37:08.210 回答
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
于 2013-06-13T11:05:31.217 回答
0

在 SQL 术语中,您需要一个游标来遍历所有表/日期列对并在每列中找到最小的日期值。您可以将结果插入到临时表中,以便根据需要对其进行分析。

抱歉,这不是 VBA,但 VBA 不会做任何工作,只是中继 SQL 命令。因此,如果您只能通过 VBA(出于任何原因)访问 db,请发送此命令,并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
于 2013-06-13T13:59:16.933 回答